【问题标题】:Option/Maybe class for C++C++ 的 Option/Maybe 类
【发布时间】:2012-10-11 08:56:23
【问题描述】:

我想在 C++ 中实现一个类 Scala 的 Option / Haskell 类的 Maybe 类。出于效率原因,我不想使用动态分配的内存,也不想使用多态性。另外,如果 Option 为 None,我不希望创建任何嵌入类型的对象。

谁能告诉我以下方法是否会导致问题?我必须在我的 Option 类中为嵌入对象静态分配内存,但我无法定义嵌入类型的成员字段,因为即使 Option 为 None,这也会在创建 Option 对象时初始化。

template <typename T>
class Option {
private:
    uint8_t _storage [sizeof (T)];
    T * _embedded;
public:
    Option () : _embedded (nullptr) {
    }

    Option (const T & obj) : _embedded (new (_storage) T (obj)) {
    }

    Option (const Option<T> & other)
    : _embedded (
        other->_embedded ? new (_storage) T (other->_embedded) : nullptr
    ) {
    }

    // ...

    ~Option () {
        if (_embedded) _embedded->~T ();
    }
};

【问题讨论】:

  • 你可以查看Boost.Optional是如何实现的。
  • 感谢您的提示。我应该知道 Boost 有它。
  • 实际上,这是一个非常巧妙的表示。您还需要处理 assignment,但除此之外,我真的很喜欢直接存储指针而不仅仅是布尔值的想法。之后肯定会让事情变得更容易。
  • 你离在这里实现一个'Variant'类型类还有半步之遥。

标签: c++ new-operator


【解决方案1】:

我不认为数组需要像对象类可能需要的那样对齐。实际上,除非该类型有有趣的对齐要求,否则我不会期望任何问题。

在 C++ 2011 中,您可以使用 union 来保存实际表示,尽管您仍然需要管理所保存对象的生命周期。有一个boost::optional&lt;T&gt; 和一个proposal 将类似的类型添加到标准的下一个修订版中。

【讨论】:

  • 您可以使用 boost::aligned_storage 来正确对齐缓冲区。
  • 根据这个问题的答案,从新位置返回未对齐的内存是 UB:stackoverflow.com/questions/11781724/…
  • 实际上,在 C++11 中,我希望使用 std::aligned_storage。它是专门为请求精确大小和对齐的原始存储而创建的。
  • 对提案结果感兴趣的人:C++17引入std::optional
【解决方案2】:

对我来说这看起来不错,除了:

uint8_t _storage [sizeof(T)/sizeof(uint8_t)];

Option (const Option & other)
    : _embedded (other->_embedded ? new (_storage)T(other->_embedded) : nullptr)
{
}

【讨论】:

猜你喜欢
  • 2015-05-21
  • 1970-01-01
  • 2017-11-23
  • 2022-01-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-17
  • 1970-01-01
相关资源
最近更新 更多