emplace(c.end()、_ 1)を使用することはemplace_back(_1)と同じだと思いますが、言語設計者が1つではなく2つの関数を提供した理由がわかりません。いくつかの情報が不足していると思います。
では、emplace(c.end()、_ 1)とemplace_back(_1)を区別するのは何ですか?
大きな違いは、コンテナの要件がに比べてvalue_type
少なくなっていることです。vector::emplace_back
deque::emplace_back
emplace
vector
唯一のことを話すdeque
:
EmplaceConstructible
からに加えてargs
;
emplace
MoveInsertable
とが必要ですがMoveAssignable
、
emplace_back
必要なのはMoveInsertable
。
を含むほとんどのアロケータはstd::allocator
、MoveInsertable
と同じMoveConstructible
です。
vector
したがって、またはに入れたいタイプがdeque
あり、それがMoveConstructible
であるが、ではないMoveAssignable
場合emplace_back
は、友達です。また、わずかに高速で、コードサイズがわずかに小さい可能性がありますが、これは実装品質の問題です(標準では保証されていません)。そして、その差はあなたが気付くよりも小さい可能性があります(注意深く測定しない限り)。
たとえば、次のようになります。
#include <vector>
struct A
{
A() = default;
A(A&&) = default;
A& operator=(A&&) = delete;
};
これはコンパイルします:
int main()
{
std::vector<A> v;
v.emplace_back();
}
しかし、これはしません:
int main()
{
std::vector<A> v;
v.emplace(v.end()); // error A is not MoveAssignable
}
ただし、変更した場合:
A& operator=(A&&) = delete;
に:
A& operator=(A&&) = default;
次に、両方の例がコンパイルされます(そして正常に実行されます)。
データ構造によっては、emplace_back
より速く作成できる場合がありemplace(c.end(), _1)
ます。たとえば、を使用std::vector
するemplace_back
と、シフトする必要のある要素(存在する場合)を確認する必要がなくなり、emplace_back
わずかに高速になります。
ええ、その場合は同等です。
emplace
最後だけでなく機能するため、より一般的です。emplace_back
書く必要がないので便利ですc.end()
。
実装には利点もあるかもしれません—あなたがそれに提供したイテレータがエンドイテレータであったことを知らemplace
ないことを思い出してください。
それでおしまい。