C语言中如何实现类似Optional的功能?

摘要:Optional 这是一个完整的 optional 类型实现,类似于 C++17 的 std::optional。 整体结构 template<class T>
Optional 这是一个完整的 optional 类型实现,类似于 C++17 的 std::optional。 整体结构 template<class T> struct optional{ private: T value; bool has_value; public: optional(T value) : value(value),has_value(has_value){} T value(){return value;} bool has_value(){return has_value;} }; 上面是一个最简单的optional结构,可以满足基本的判断有无值,取出值等。 但是过于简单,很多都没有考虑到,比如,我们指定了类型T,那么构建otional的时候无论值是否存在,value都会被构造。有着不必要的构造和析构等等... 实现 union包装 既然无论有值与否都会构造析构,那么有没有可以没有值就不构造的方法呢?在C++中,union类型的对象默认不会自动构造和析构函数。因为union可能含有多个成员,而union自己是不知道当前成员是谁的,也就无从谈起自动构造和析构。 union{ T value; }; 这样使用union存储值,可以精确的控制构造和析构时机。 值构造 optional(T &&value) noexcept : _has_value(true) { new (&_value) T(std::move(value)); } optional(T const &value) noexcept : _has_value(true) { new (&_value) T(value); } 我们提供了两种从值构造的方式,分别是右值和左值构造。 重点在于value的构造,union默认开辟最大成员成员所占内存。因为我们这里的union只有一个value,那么所占内存就是T的字节大小。我们要做的就是从已经开辟好的内存直接构造T.使用placement new在union内存构造对象; new (&value) T(value); 在value的内存上,以value(参数value)为值构造union成员value. 空状态构造 我们需要支持当不存在值时的构造。方法是可以先创建一个空状态的辅助类型。 struct nullopt_t { explicit nullopt_t() = default; }; inline constexpr nullopt_t nullopt; 我们这里创建了 nullopt_t 类型,同时添加了全局的 nullopt 对象。这样我们实现一个空构造的函数,只要传入代表空的辅助类型,就说明为 optional 空。 optional(nullopt_t) noexcept : _has_value(false) {} optional() noexcept : optional(nullopt) {} 拷贝/移动 其他的拷贝/移动的构造或者赋值函数形式大差不差,一通百通。
阅读全文