c++ std::可选类的实现

r1zhe5dt  于 2022-11-19  发布在  其他
关注(0)|答案(5)|浏览(288)

我需要为可选值实现一个快速的解决方案。我不想拖任何第三方库。
一般来说,可选类是如何实现的?当一个可选对象处于“空状态”时,它仍然默认构造底层对象吗?

lnxxn5zx

lnxxn5zx1#

一般来说,可选类是如何实现的?
通常,一个布尔标志用于指示它是否为空,一个大小合适且对齐的字节数组用于存储值。
当可选对象处于“空状态”时,它仍然默认构造底层对象吗?
不,这会对存储类型施加不必要的要求,并导致潜在的不必要的副作用。当optional变为非空时,存储对象将使用placement-new创建,而当它变为空时,将使用析构函数调用销毁。
对于一个快速和肮脏的实现,如果你不需要Boost或建议的标准版本的所有灵活性,你可以简单地存储一个默认构造的对象。
我不想引入任何第三方库。
我会重新考虑为什么你不想这样做。Boost实现是只有头文件的,经过了良好的测试,如果标准版本出现,应该可以直接替换它。我当然更相信它,而不是我自己拼凑起来的东西。

9q78igpj

9q78igpj2#

首先,我强烈建议你看一看Boost(特别是Boost.Optional)--使用Boost几乎是标准的做法,它可以保存你重新发明轮子。
如果出于某种原因,您不愿意使用Boost.Optional,有许多类似的只包含头文件的库,例如https://github.com/akrzemi1/Optional

bpzcxfmw

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

thigvfpy

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;}
};

相关问题