訪問者が言ったことに加えて:
void emplace_back(Type&& _Val)
MSCV10が提供する機能は、厳密にはと同等であるため、非準拠で冗長ですpush_back(Type&& _Val)
。
しかし、実際のC ++ 0x形式emplace_back
は非常に便利ですvoid emplace_back(Args&&...)
。
を受け取る代わりにvalue_type
、引数の可変リストを受け取ります。つまり、引数を完全に転送し、一時オブジェクトをまったく使用せずにオブジェクトを直接コンテナーに構築できるようになります。
RVOと移動のセマンティックがどれだけ巧妙にテーブルにもたらされても、push_backが不要なコピー(または移動)を作成する可能性が高い複雑なケースがあるため、これは便利です。たとえば、の従来のinsert()
関数ではstd::map
、一時ファイルを作成する必要があります。一時ファイルは次ににコピーされ、std::pair<Key, Value>
次にマップにコピーされます。
std::map<int, Complicated> m;
int anInt = 4;
double aDouble = 5.0;
std::string aString = "C++";
// cross your finger so that the optimizer is really good
m.insert(std::make_pair(4, Complicated(anInt, aDouble, aString)));
// should be easier for the optimizer
m.emplace(4, anInt, aDouble, aString);
では、MSVCに正しいバージョンのemplace_backを実装しなかったのはなぜですか?実際、かなり前からバグがあったため、Visual C ++ブログで同じ質問をしました。MicrosoftのVisual C ++標準ライブラリ実装の公式メンテナであるStephan T Lavavejからの回答です。
Q:現在、ベータ2エンプレース機能は、ある種のプレースホルダーにすぎませんか?
A:ご存知かもしれませんが、可変テンプレートはVC10に実装されていません。make_shared<T>()
、タプル、およびの新しいものなどのプリプロセッサマシンでそれらをシミュレートします
<functional>
。このプリプロセッサー機構は、使用および保守が比較的困難です。また、サブヘッダーを繰り返し含める必要があるため、コンパイル速度に大きく影響します。時間の制約とコンパイル速度の懸念の組み合わせにより、私たちはemplace関数で可変テンプレートをシミュレートしていません。
可変個のテンプレートがコンパイラーに実装されている場合は、emplace関数を含むライブラリーでそれらを利用することが期待できます。私たちは適合性を非常に真剣に受け止めていますが、残念ながら、すべてを一度にすべて行うことはできません。
それは理解できる決断です。プリプロセッサの恐ろしいトリックを使って可変テンプレートをエミュレートすることを一度だけ試みた人は誰でも、これがいかに嫌なことかを知っています。