2017-04-23 3 views
0

クラスの初期化で必要なコンストラクタを選択するには、クラス内のinitの割り当てスタイルを使用する必要があるようです。クラス内のinit(代入スタイル)とコンストラクタのパフォーマンス

class Foo { 
    // This lets me sets the vector size 
    std::vector<char> buf = std::vector<char>(BUF_SIZE); 

    // this didn't compile and made me realize finding another way to provide constructor parameters was necessary 
    // std::vector<char> buf{BUF_SIZE}; 
}; 

これは2つのオブジェクトが構築され、このスタイルで「BUF」を初期化することを意味しています、代入演算子が呼び出され、第二の目的は、破壊されましたか?または、これは単なる構文的な砂糖であり、生成されるコードは次のようになります。

class Bar { 
public: 
    Bar() : buf(BUF_SIZE) {} 

    std::vector<char> buf; 
}; 

これはおそらくコンパイラ固有ですか?

+2

は 'のstd ::ベクトル BUF {BUF_SIZE}'と 'のstd ::ベクトル BUF(BUF_SIZE)は'異なることを行う - あなたはどちらをしたいですか? – UnholySheep

+1

良いコンパイラであればそれはなくなってしまいますが、C++ 17では、とにかくエリートすることはありません。 – chris

+0

私の目標は、私の目標が初期値のどんな種類を提供するのではなく、ベクトルの初期化サイズを設定することだったことを示すために投稿を明確にしました。 – Kevin

答えて

0

良いコンパイラはコピーを消去し、単一のベクトルを構成します。


この最適化を無効にすると、C++ 11でコンパイルするかどうかによって異なります。

std::vector<char> buf = std::vector<char>(BUF_SIZE); 
  • 前にC++ 11、いずれか:私は特にこの行を見ています、(非静的メンバ初期化子は、C++ 11の特徴であるように)クラスのメンバーであることのコンテキストがなけれベクターは(一時的に)構築され、bufはこの一時的なものから複製構築され、一時的なものは破壊される。ベクトルが大きい場合は、実際には非常に非効率的である可能性があります。
  • C++ 11からは、一時的に構築され、次にbufになるでしょう。からそれがあります。 bufは、データポインタを一時的なものから「盗む」ことになり、一時的な状態を不特定の(しかし有効な)状態にしておき、一時的なものを破棄する。このプロセスのオーバーヘッドは簡単で一定です。
+1

C++ 11より前では、その構文は無効でした。 ;-) – Jarod42

+0

ありがとう!要約すると:C++ 11では、クラス内の割り当てスタイルを持つ非静的データメンバーを初期化できます。これは、常に可能だった静的データメンバーを初期化するのと同じです。 C++ 11では、両方のケースをより効率的にする移動構造も追加されました。上記の@Chrisによると、C++ 17は、それをさらに改善するために "保証された" elisionを追加しました:en.cppreference.com/w/cpp/language/copy_elision – Kevin

関連する問題