将emplace_back与unique_ptrs容器一起使用是否安全?

Bil*_*eal 20 c++ exception-safety emplace

考虑以下:

std::vector<std::unique_ptr<int>> ptrsToInts;
ptrsToInts.emplace_back(new int);
Run Code Online (Sandbox Code Playgroud)

如果在向量中发生重新分配,并且失败(抛出std::bad_alloc),我是"安全"还是会泄漏int

C++ 11 23.3.6.5 [vector.modifiers]/1说:

如果除了复制构造函数之外抛出异常,则移动构造函数,赋值运算符或移动赋值运算符T或通过任何InputIterator运算都没有效果.

这似乎表明这是一个潜在的问题.也就是说,如果存在"无效果",则unique_ptr从未构造过,因此delete不会发生依赖于该指针的析构函数行为.(这可能表明emplace_back应该禁止容器的unique_ptrs)

Nic*_*las 19

如果需要重新分配并且失败,那么是的,您的对象永远不会进入容器,因此将丢失.

但是,应该注意这是纯粹的用户错误.emplace_back不应该为容器"禁止" unique_ptr,因为有完全安全的方法这样做(例如reserve预先占用空间,所以你知道它将永远存在).此外,您可以传入整个unique_ptrs,因为它完全能够使用移动构造函数.

实际上,int*在你可以抛出异常的点之前没有正确地将非RAII对象(the )包装在RAII对象中是你的错.

  • 啊 - 但是对象从未进入过.Inglacement在向量内存块本身内就地构造对象.传入的是指针,而不是`unique_ptr`.当然,指针被破坏了,但是我能保证`unique_ptr`的析构函数运行并删除指针吗? (2认同)
  • 呃,从什么时候开始这里需要分配“错误”了?至于有“完全安全”的方法可以做到这一点,当然,有“安全”的方法可以做到这一点。但是,如果您强制使用移动构造函数,您也可能只使用“push_back”,因为它在所有情况下都会强制执行正确的行为。 (2认同)