Ser*_*eyA 9 c++ language-lawyer c++11
std::map::emplace在标准中以某种方式创建对象(即调用构造函数)的点是什么?如果是,是否在检查此类密钥存在之前或之后发生?
在以下情况下,这很重要:
struct X {};
std::map<int, std::unique_ptr<X> > map;
void f(int x) {
map.emplace(x, new X);
}
Run Code Online (Sandbox Code Playgroud)
如果首先创建对象,则一切都很酷(构造unique_ptr并拥有资源),但如果在检查后构造它,则在重复键的情况下存在内存泄漏.
所有我能在标准中找到的是
插入一个value_type对象t,使用
std::forward<Args>(args)...if和仅当容器中没有元素且使用等效于t的键的元素构造 .
这没有解决我的问题.
T.C*_*.C. 12
这确实是不明确的,这部分是为什么C++ 17增加try_emplace了解决语义的原因.N3873是该try_emplace提案的早期版本,对现有措辞进行了很好的讨论.
在一般情况下,它必须是"之前",因为"之后"是不可实现的,如果它强加了这样的要求,标准就会有缺陷.考虑emplace(piecewise_construct, forward_as_tuple(foo, bar), forward_as_tuple(meow, purr)).因为键和值不需要是可移动的,所以你几乎必须首先构造对象并检查键的存在,因为你不能在没有键的情况下检查键的存在.
然而,实施可能需要特殊情况并不是不可想象的emplace(key_type, something); 当密钥存在时,避免支付所需的分配+构造+破坏+解除分配通常是一件好事.
| 归档时间: |
|
| 查看次数: |
714 次 |
| 最近记录: |