web-dev-qa-db-ja.com

値をコピーせずにstd :: map emplace

C++ 11 std::map<K,V>タイプには、他の多くのコンテナと同様に、emplace関数があります。

std::map<int,std::string> m;

std::string val {"hello"};

m.emplace(1, val);

このコードは、広告通りに機能し、std::pair<K,V>直接、ただしkeyvalのコピーが行われます。

値タイプをマップに直接埋め込むこともできますか? emplaceの呼び出しで引数を移動するよりも良い方法がありますか?


以下に、より詳細な例を示します。

struct Foo
{
   Foo(double d, string s) {}
   Foo(const Foo&) = delete;
   Foo(Foo&&) = delete;
}

map<int,Foo> m;
m.emplace(1, 2.3, string("hello")); // invalid
47
Drew Noakes

map::emplaceに渡す引数は、map::value_typeのコンストラクター(pair<const Key, Value>)に転送されます。そのため、 piecewise construction constructor of std::pairを使用して、中間コピーと移動を回避できます。

std::map<int, Foo> m;

m.emplace(std::piecewise_construct,
          std::forward_as_Tuple(1),
          std::forward_as_Tuple(2.3, "hello"));

ライブデモ

66
Praetorian

C++ 17では、これは try_emplace メソッド。

map<int,Foo> m;
m.try_emplace(1, 2.3, "hello");

標準ライブラリへのこの追加は paper N4279 で説明されており、 Visual Studio 2015GCC 6.1 および LLVMで既にサポートされているはずです3.7 (libc ++ライブラリ)。

16