1

emplace(c.end()、_ 1)を使用することはemplace_back(_1)と同じだと思いますが、言語設計者が1つではなく2つの関数を提供した理由がわかりません。いくつかの情報が不足していると思います。

では、emplace(c.end()、_ 1)とemplace_back(_1)を区別するのは何ですか?

4

3 に答える 3

5

大きな違いは、コンテナの要件がに比べてvalue_type少なくなっていることです。vector::emplace_backdeque::emplace_backemplace

vector唯一のことを話すdeque

EmplaceConstructibleからに加えてargs;

emplaceMoveInsertableとが必要ですがMoveAssignable

emplace_back必要なのはMoveInsertable

を含むほとんどのアロケータはstd::allocatorMoveInsertableと同じ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;

次に、両方の例がコンパイルされます(そして正常に実行されます)。

于 2013-02-16T21:52:33.273 に答える
2

データ構造によっては、emplace_backより速く作成できる場合がありemplace(c.end(), _1)ます。たとえば、を使用std::vectorするemplace_backと、シフトする必要のある要素(存在する場合)を確認する必要がなくなり、emplace_backわずかに高速になります。

于 2013-02-16T21:21:17.267 に答える
1

ええ、その場合は同等です。

emplace最後だけでなく機能するため、より一般的です。emplace_back書く必要がないので便利ですc.end()

実装には利点もあるかもしれません—あなたがそれに提供したイテレータがエンドイテレータであったことを知らemplaceないことを思い出してください。

それでおしまい。

于 2013-02-16T21:15:51.510 に答える