0

このブースト ドキュメントについて考えてみましょう: http://www.boost.org/doc/libs/1_35_0/libs/utility/in_place_factories.html

エキス:

struct C
{
   template<class InPlaceFactory>
   C ( InPlaceFactory const& aFactoty )
    :
    contained_ ( uninitialized_storage() )
   {
     aFactory.template apply<X>(contained_);
   }

  char* uninitialized_storage() { return new char[sizeof(X)] ; }

  char* contained_ ;
} ;

実際には、C++ コンパイラは初期化リスト中にクラス メンバ コンストラクタを呼び出すため、プリプロセッサ (またはプリコンパイラ) なしでは in-place-factory から引数を拡張することはできません。したがって、デフォルトのコンストラクターが呼び出されるのを避けるために、メンバーの型を に変更しchar*ます。

私が断言するのは、これは悲しいことだということです。

contained_それが意図したタイプだったと想像してくださいX

コンストラクターがまったく呼び出されないようにする方法はありませんか? メンバーを初期化されていない状態にします。これは、型の正しいスペースとアラインメント要件を備えたバイトのプールであるかのように、必要なコンストラクターを自由に呼び出すことができますplacement new。 -place-factory は) ?

このようにすれば、アラインメントの問題や可読性の問題は発生しませchar*ん。

また、in-place-factory 表記を使用できますが、X型ではなく、char*型に対して使用できます。

また、答えを考えるときは、構造体Cがスタック上でインスタンス化されている場合、ソリューションが直接その場で機能できる必要があることを常に心に留めておいてください。ポインターもヒープ割り当ても必要ありません。contained_オブジェクトはその場に留まる必要があります、スタック上。

元のブースト ソリューションではnew、16 バイトのアラインメントを利用していることがわかります (Microsoft CRT 2014 では、4096 より大きいオブジェクトの場合は 32 バイトになりました)。そうでなければ、より自然な表記法によって引き起こされる位置合わせの問題を効果的に回避します。

char contained_[sizeof(X)];

もちろん、「修正」は__declspec(align(alignof(X)))の宣言の前のようなものを使用することですcontained_が、私が言ったように、char 配列を使用することは保守可能な解決策とは言えず、使用するたびにキャストする必要がありますcontained_...

ありがとう !

4

0 に答える 0