1. ホーム
  2. c++

[解決済み] push_back vs emplace_back

2022-03-22 01:43:37

質問

との違いについて、少し混乱しています。 push_backemplace_back .

void emplace_back(Type&& _Val);
void push_back(const Type& _Val);
void push_back(Type&& _Val);

があるため push_back の目的は何なのでしょうか? emplace_back になるのでしょうか?

どのように解決するのですか?

お客様がおっしゃったことに加えて.

機能 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を実装しなかったのでしょうか?実は、ちょっと前に私も気になったので、同じ質問を ビジュアルC++ブログ . MicrosoftのVisual C++標準ライブラリ実装の公式メンテナであるStephan T Lavavejからの回答は以下のとおりです。

<ブロッククオート

Q: ベータ 2 の emplace 関数は、今は単なるプレースホルダーのようなものですか?

A: ご存知のように、バリアディックテンプレートは は、VC10には実装されていません。私たちは プリプロセッサーでシミュレート のような機械があります。 make_shared<T>() やタプル、そして新しい のものは <functional> . この プリプロセッサの機械は比較的 使いこなしやメンテナンスが難しい。また コンパイルに大きな影響を与える を繰り返し行わなければならないため、速度が低下します。 はサブヘッダを含む。そのため 時間的な制約もあり とコンパイル速度の問題から 変種テンプレートのシミュレーションは行っていない をemplace関数に追加しました。

可変個体テンプレートが コンパイラに実装されると を活用することが期待されます。 を含むライブラリで使用されています。 エンプレイス関数 私たちは コンフォーマンスは非常に重要ですが 残念ながら、すべてを を一挙に公開します。

それは理解できる判断です。プリプロセッサの恐ろしいトリックを使ってバリアディックテンプレートをエミュレートしようとしたことがある人なら誰でも、このネタがどれほど嫌なものになるかを知っているはずです。