这里是一个示例代码:
struct T
{
T(int x) : x_(x)
{}
T(T&&) = delete;
T(const T&) = delete;
int x_;
};
int main()
{
std::unordered_map<int, T> m;
m.emplace(std::piecewise_construct, std::forward_as_tuple(1), std::forward_as_tuple(2));
m.emplace(std::piecewise_construct, std::forward_as_tuple(1), std::forward_as_tuple(2));
return 0;
}
第二个 emplace 失败,但 T 构造函数被调用两次。我认为,只有当可以插入时, emplace 才会构造一个对象。你能解释一下吗?
编辑: 我使用 Visual Studio 2017 编译器。
最佳答案
来自cppreference :
The element may be constructed even if there already is an element with the key in the container, in which case the newly constructed element will be destroyed immediately.
出现这种行为的原因是容器需要构造一个关键对象才能检查它是否已经存在;映射对象必须同时构造,因为它们是同一对象(value_type
对)的成员。
try_emplace
(C++17 起) 在这种情况下是更好的选择,因为它只会在插入成功时构造映射对象。它之所以能够做到这一点,是因为它将键作为第一个参数,并从其余参数中放置映射对象,从而产生更好的界面:
m.try_emplace(1, 2);
m.try_emplace(1, 2);
^ key (copied or moved)
^ mapped_type emplacement args (forwarded)
关于c++ - unordered_map和emplace,为什么ctor被调用两次?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59934332/