このブースト ドキュメントについて考えてみましょう: 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_
...
ありがとう !