C++0x では、各コンテナに emplace/emplace_back/emplace_front/emplace_hint というメンバ関数が追加されます。
こういうクラスがあった場合
struct something { something(int, int, int); };
something をコンテナの要素として追加する場合、 C++03 では以下のようにしていました。
vector<something> v; v.push_back(something(1, 2, 3));
この方法では、 something のコンストラクタによる一時オブジェクトの生成と、コピーのコストが発生します。
Placement Insert では、可変引数テンプレートによって要素型のコンストラクタ引数を受け取ることで
要素をコンテナ内で一度だけ生成し、コピーのコストをなくします。
vector<something> v; v.emplace_back(1, 2, 3); // emplace_backの内部でsomething(1, 2, 3)が呼ばれる
重いオブジェクトを要素とするコンテナでは、 Placement Insert は非常に重要になります。
ただし、 Placement Insert にはいくつか注意事項があります。
【explicitの問題】
コンストラクタの引数を受け取るため、 explicit なコンストラクタでも暗黙に呼び出せるように見えてしまいます。
struct something { explicit something(int); }; vector<something> v; v.emplace_back(3); // 内部でsomething(3)が"明示的に"呼び出される
【0問題】
可変引数テンプレートを使用しているため、ヌルポインタのために 0 (NULLマクロ含む)を渡そうとすると
テンプレートによって int に推論されてしまいます。
なので、 Placement Insert にヌルポインタを渡す場合は、 nullptr を使用しましょう。
struct something { something(int*); }; vector<something> v; v.emplace_back(0); // エラー! v.emplace_back(NULL); // エラー! v.emplace_back(nullptr); // OK
emplace_back は push_back の Placment Insert 版
emplace_front は push_front の Placement Insert 版
emplace は insert の Placement Insert 版
emplace_hint は insert の Placement Insert 版で、第1引数で const_iterator を受け取る(連想コンテナ用)
です
N2680 Proposed Wording for Placement Insert (Revision 1)(日本語訳)