考虑以下尝试vector
在 a 中用数字键放置一个空map
:
#include <map>
#include <vector>
int main () {
std::map<size_t, std::vector<size_t>> m;
m.emplace(42, {}); // FAILS
m.insert({42, {}}); // WORKS
}
调用emplace
未能解决:
error: no matching function for call to ‘std::map<long unsigned int, std::vector<long unsigned int> >::emplace(int, <brace-enclosed initializer list>)’
m.emplace(42, {});
^
In file included from /usr/include/c++/8/map:61,
from map_emplace.cpp:1:
/usr/include/c++/8/bits/stl_map.h:574:2: note: candidate: ‘std::pair<typename std::_Rb_tree<_Key, std::pair<const _Key, _Tp>, std::_Select1st<std::pair<const _Key, _Tp> >, _Compare, typename __gnu_cxx::__alloc_traits<_Alloc>::rebind<std::pair<const _Key, _Tp> >::other>::iterator, bool> std::map<_Key, _Tp, _Compare, _Alloc>::emplace(_Args&& ...) [with _Args = {}; _Key = long unsigned int; _Tp = std::vector<long unsigned int>; _Compare = std::less<long unsigned int>; _Alloc = std::allocator<std::pair<const long unsigned int, std::vector<long unsigned int> > >; typename std::_Rb_tree<_Key, std::pair<const _Key, _Tp>, std::_Select1st<std::pair<const _Key, _Tp> >, _Compare, typename __gnu_cxx::__alloc_traits<_Alloc>::rebind<std::pair<const _Key, _Tp> >::other>::iterator = std::_Rb_tree_iterator<std::pair<const long unsigned int, std::vector<long unsigned int> > >]’
emplace(_Args&&... __args)
^~~~~~~
/usr/include/c++/8/bits/stl_map.h:574:2: note: candidate expects 0 arguments, 2 provided
尝试对向量的向量做同样的事情按预期工作(编辑:不使用时emplace_back
,参见 Bo Persson 的回答):
std::vector<std::vector<size_t>> v;
v.emplace({}); // WORKS -- but does the wrong thing!
v.emplace_back({}); // FAILS
v.push_back({{}}); // WORKS
我对背后逻辑的粗略理解emplace
是调用emplace
和insert
应该给出相同的结果,不同之处在于 emplace 既不需要移动也不需要复制。对于这些类型,使用版本并没有太大的危害insert
,因为向量的内容会被移动(在这种特定情况下,向量无论如何都是空的)。但总的来说,为什么这会失败std::map::emplace
?使用 GCC 8.1。