102

C++ 11では、インプレース構築が可能であるemplace_back()ため、一般的に(効率の観点から)好まれますが、構築済みのオブジェクトを使用する場合はまだそうですか?push_back()push_back(std::move())

たとえばemplace_back()、次のような場合でも優先されますか?

std::string mystring("hello world");
std::vector<std::string> myvector;

myvector.emplace_back(mystring);
myvector.push_back(std::move(mystring));
// (of course assuming we don't care about using the value of mystring after)

さらに、上記の例で代わりに次のことを行う利点はありますか?

myvector.emplace_back(std::move(mystring));

または、ここでの移動は完全に冗長であるか、効果がありませんか?

4

2 に答える 2

132

あなたが提供したさまざまな呼び出しが何をするか見てみましょう。

  1. emplace_back(mystring): これは、指定した引数を使用した新しい要素のインプレース構築です。左辺値を指定したため、そのインプレース構築は実際にはコピー構築です。つまり、これは呼び出しと同じですpush_back(mystring)

  2. push_back(std::move(mystring)): これは move-insertion を呼び出しますstd::string

  3. emplace_back(std::move(mystring)): これも、指定した引数を使用したインプレース構築です。その引数は右辺値であるため、 の移動コンストラクタを呼び出しますstd::string。つまり、2 のようなインプレース移動構築です。

つまり、型 T の 1 つの引数で呼び出された場合、それは右辺値または左辺値でemplace_backありpush_back、同等です。

ただし、他の引数についてemplace_backは、たとえば a の a を使用して、競合に勝ちchar const*ますvector<string>

  1. emplace_back("foo")std::string(char const*)インプレース建設を求めています。

  2. push_back("foo")最初にstd::string(char const*)、関数のシグネチャに一致するために必要な暗黙的な変換を呼び出す必要があり、次に上記のケース 2 のような移動挿入を呼び出す必要があります。したがって、それはpush_back(string("foo"))

于 2014-11-11T09:27:05.623 に答える