2012-10-21 93 views
5

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

有人可以告诉我以下方法是否会导致问题?我必须为我的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(); 
    } 
}; 
+2

你可以检查[Boost.Optional](http://www.boost.org/doc/libs/1_51_0/libs/optional/doc/html/index.html)是如何实现的。 – kennytm

+0

感谢您的提示。我应该知道Boost有它。 – JohnB

+1

实际上这是一个非常聪明的表示。你也需要处理**赋值**,否则我真的很喜欢直接存储指针而不是布尔值的想法。让事情变得更容易。 –

回答

3

我不认为数组需要对准相同的方式对象类,可能需要。在实践中,我不会期望任何问题,除非这种类型具有有趣的对齐要求。

使用C++ 2011,您可以使用union来保存实际表示,但您仍然需要管理保留对象的生命周期。有一个boost::optional<T>和一个proposal为该标准的下一个版本添加一个类似的类型。

+0

您可能可以使用boost :: aligned_storage以获得缓冲区的正确对齐。 – mauve

+0

根据这个问题的答案返回不对齐的内存从新的位置UB:http://stackoverflow.com/questions/11781724/do-i-really-have-to-worry-about-alignment-when-using-placement -new-operator – PiotrNycz

+0

其实,在C++ 11中,我期望使用'std :: aligned_storage'。它是专门为要求精确尺寸*和对齐*的原始存储而创建的。 –

1

对于我来说,这看起来很好,除了:

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

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

'char _storage [sizeof(T)];'因为['char'总是1](http://en.cppreference.com/w/cpp/language/sizeof)大小? – Wolf