我需要为可选值实现一个快速的解决方案。我不想拖任何第三方库。一般来说,可选类是如何实现的?当一个可选对象处于“空状态”时,它仍然默认构造底层对象吗?
lnxxn5zx1#
一般来说,可选类是如何实现的?通常,一个布尔标志用于指示它是否为空,一个大小合适且对齐的字节数组用于存储值。当可选对象处于“空状态”时,它仍然默认构造底层对象吗?不,这会对存储类型施加不必要的要求,并导致潜在的不必要的副作用。当optional变为非空时,存储对象将使用placement-new创建,而当它变为空时,将使用析构函数调用销毁。对于一个快速和肮脏的实现,如果你不需要Boost或建议的标准版本的所有灵活性,你可以简单地存储一个默认构造的对象。我不想引入任何第三方库。我会重新考虑为什么你不想这样做。Boost实现是只有头文件的,经过了良好的测试,如果标准版本出现,应该可以直接替换它。我当然更相信它,而不是我自己拼凑起来的东西。
optional
9q78igpj2#
首先,我强烈建议你看一看Boost(特别是Boost.Optional)--使用Boost几乎是标准的做法,它可以保存你重新发明轮子。如果出于某种原因,您不愿意使用Boost.Optional,有许多类似的只包含头文件的库,例如https://github.com/akrzemi1/Optional
bpzcxfmw3#
在c++14或更早的版本中,你可以使用一个空值检查过的T*,或者只使用一个std::pair<T, bool>。后者的问题是如果你默认的T构造是昂贵的,那可能是浪费。在c++17或更高版本中,您仍然可以使用T*,但您也可以使用std::optional<T>。在这里,后者仅在T有效的情况下构造T。值得注意的是,std::optional仅在少数情况下是不错的选择:https://topanswers.xyz/cplusplus?q=923#a1085
T*
std::pair<T, bool>
T
std::optional<T>
std::optional
thigvfpy4#
这里是一个模仿std::optional的开始。这不是最棘手的实现,还有很多应该添加的内容。
template <typename T> struct optional { private: bool _has_value; T _value; public: optional() : _has_value{false}, _value{} {} optional(T v) : _has_value{true}, _value{v} {} bool has_value() const {return _has_value;} T value() const { if (_has_value) return _value; throw std::bad_optional_access(); } T value_or(T def) const { return _has_value ? _value : def; } optional<T>& operator=(T v) { _has_value = true; _value = v; return *this; } void reset() {_has_value = false;} };
kgsdhlau5#
std::optional from Scratch介绍如何实现可选类
5条答案
按热度按时间lnxxn5zx1#
一般来说,可选类是如何实现的?
通常,一个布尔标志用于指示它是否为空,一个大小合适且对齐的字节数组用于存储值。
当可选对象处于“空状态”时,它仍然默认构造底层对象吗?
不,这会对存储类型施加不必要的要求,并导致潜在的不必要的副作用。当
optional
变为非空时,存储对象将使用placement-new创建,而当它变为空时,将使用析构函数调用销毁。对于一个快速和肮脏的实现,如果你不需要Boost或建议的标准版本的所有灵活性,你可以简单地存储一个默认构造的对象。
我不想引入任何第三方库。
我会重新考虑为什么你不想这样做。Boost实现是只有头文件的,经过了良好的测试,如果标准版本出现,应该可以直接替换它。我当然更相信它,而不是我自己拼凑起来的东西。
9q78igpj2#
首先,我强烈建议你看一看Boost(特别是Boost.Optional)--使用Boost几乎是标准的做法,它可以保存你重新发明轮子。
如果出于某种原因,您不愿意使用Boost.Optional,有许多类似的只包含头文件的库,例如https://github.com/akrzemi1/Optional
bpzcxfmw3#
在c++14或更早的版本中,你可以使用一个空值检查过的
T*
,或者只使用一个std::pair<T, bool>
。后者的问题是如果你默认的T
构造是昂贵的,那可能是浪费。在c++17或更高版本中,您仍然可以使用
T*
,但您也可以使用std::optional<T>
。在这里,后者仅在T
有效的情况下构造T
。值得注意的是,
std::optional
仅在少数情况下是不错的选择:https://topanswers.xyz/cplusplus?q=923#a1085thigvfpy4#
这里是一个模仿std::optional的开始。这不是最棘手的实现,还有很多应该添加的内容。
kgsdhlau5#
std::optional from Scratch介绍如何实现可选类