web-dev-qa-db-ja.com

push_backまたはemplace_backとstd :: make_unique

これら質問ここ の回答に基づいて、c ++ 14の_std::make_unique_を使用するよりも使用する方が確かに好ましいことを私は知っていますemplace_back(new X)直接。

とは言うものの、

_my_vector.Push_back(std::make_unique<Foo>("constructor", "args"));
_

または

_my_vector.emplace_back(std::make_unique<Foo>("constructor", "args"));
_

つまり、_Push_back_から構築された_emplace_back_を追加するときに、_std::unique_ptr_または_std::make_unique_を使用する必要がありますか?

====編集====

なぜ? c:<-(小さな笑顔)

18
NHDaly

新しいオブジェクトの構築に関する限り、違いはありません。すでにunique_ptr<Foo> prvalue(make_uniqueの呼び出しの結果)があるため、Push_backemplace_backの両方が要素を構築するときにunique_ptr移動コンストラクターを呼び出しますvectorに追加されます。

ユースケースに挿入後に新しく構築された要素へのアクセスが含まれる場合、emplace_backは要素への参照を返すため、C++ 17以降より便利です。だから代わりに

my_vector.Push_back(std::make_unique<Foo>("constructor", "args"));
my_vector.back().do_stuff();

あなたは書ける

my_vector.emplace_back(std::make_unique<Foo>("constructor", "args")).do_stuff();
15
Praetorian

明らかに

template<class T, class A, class...Args>
void Push_unique( std::vector<std::unique_ptr<T>,A>& v, Args&&...args ) {
  v.Push_back( std::make_unique<T>(std::forward<Args>(args)...) );
}

最良のオプションです:

Push_unique(my_vector,"constructor", "args");

悲しいことに、これは接頭辞表記です:(演算子、コンテナ、引数...)対中置(コンテナ演算子引数...)。

拡張メソッド または 名前付き演算子 のように、中置にする方法があれば。

それはかっこいいから。