2012-10-21 6 views
5

私はScalaのようなOption/HaskellのようなMaybeクラスをC++で実装したいと思います。効率の理由から、私は動的に割り当てられたメモリを使いたくないし、多形性を使いたくない。また、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

ヒントをありがとう。私はブーストが持っていることを知っていたはずです。 – 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'は常に1](http://en.cppreference.com/w/cpp/language/sizeof)なので' char_storage [sizeof(T)];はどうでしょうか? – Wolf

関連する問題