这个问题是巨大的物体将被复制到地图中
Huge huge1(some,args);
Huge huge2(some,args);
std::map<int,Huge> map1;
std::map<Huge,int> map2;
map1.insert({0,huge1});
map2.insert({huge2,0});
Run Code Online (Sandbox Code Playgroud)
我怎么能保证搬家?这会有用还是有更多呢?
map1.insert({0,std::move(huge1)});
map2.insert({std::move(huge2),0});
Run Code Online (Sandbox Code Playgroud)
Cha*_*via 46
std::map::insert R值超载:
std::pair<iterator,bool> insert(value_type&&);
任何绑定到此重载的表达式都将调用R值构造函数.既然std::map<K,V>::value_type是std::pair<const key_type, mapped_type>,并且std::pair有一个带R值的构造函数:
template<class U1, class U2>
pair(U1&& x, U2&& y);
Run Code Online (Sandbox Code Playgroud)
然后,只要您使用创建R值的表达式插入对key_type,mapped_type就可以保证在pair对象的创建和地图插入中都会调用R值构造函数,例如:
map1.insert(std::make_pair(0, Huge());
Run Code Online (Sandbox Code Playgroud)
要么
map1.insert(std::make_pair(0, std::move(huge1));
Run Code Online (Sandbox Code Playgroud)
当然,所有这些都取决于Huge具有适当的R值构造函数:
Huge(Huge&& h)
{
...
}
Run Code Online (Sandbox Code Playgroud)
最后,std::map::emplace如果您只想将新Huge对象构造为地图中的元素,也可以使用.
Nic*_*las 16
你可以这样做({0,std::move(huge1)}部分).但你也可以跳过中间人(假设你正在构建函数内的对象),如下所示:
map1.emplace(std::piecewise_construct, 0, std::forward_as_tuple(some, args));
map2.emplace(std::piecewise_construct, std::forward_as_tuple(some, args), 0);
Run Code Online (Sandbox Code Playgroud)
或者,如果您的函数被赋予了对象,您仍然可以使用emplace:
map1.emplace(0, std::move(huge1));
map2.emplace(std::move(huge1), 0);
Run Code Online (Sandbox Code Playgroud)
可以使用避免复制和移动的替代方案std::map::emplace().从链接的参考页面:
将新元素插入容器.元素就地构造,即不执行复制或移动操作.使用与提供给函数的完全相同的参数调用元素类型(value_type,即std :: pair)的构造函数,使用std :: forward(args)转发....