C++ 使用带有独特PTR容器的emplace_back安全吗?

C++ 使用带有独特PTR容器的emplace_back安全吗?,c++,emplace,exception-safety,C++,Emplace,Exception Safety,考虑以下几点: std::vector<std::unique_ptr<int>> ptrsToInts; ptrsToInts.emplace_back(new int); std::vector ptrsToInts; ptrsToInts。向后放置(新int); 如果在向量中发生重新分配,并且失败(抛出std::bad_alloc),我是“安全”还是泄漏int C++11 23.3.6.5[vector.modifiers]/1说: 如果异常不是由T的复制构造函

考虑以下几点:

std::vector<std::unique_ptr<int>> ptrsToInts;
ptrsToInts.emplace_back(new int);
std::vector ptrsToInts;
ptrsToInts。向后放置(新int);
如果在向量中发生重新分配,并且失败(抛出
std::bad_alloc
),我是“安全”还是泄漏
int

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

如果异常不是由
T
的复制构造函数、移动构造函数、赋值运算符或移动赋值运算符引发的,或者是由任何
inputierator
操作引发的,则不会产生任何影响


这似乎表明这是一个潜在的问题。也就是说,如果没有“影响”,那么就不会构造
唯一的_ptr
,因此,可以依赖的析构函数行为将
删除该指针。(这可能表明,对于
唯一的\u ptr
s容器,应禁止
安置回

如果需要重新分配,但它失败,则是的,您的对象从未进入容器,因此将丢失

但是,应该注意,这纯粹是用户错误<对于
unique\u ptr
的容器,code>emplace\u back
不应被“禁止”,因为有完全安全的方法可以做到这一点(例如
事先保留空间,这样你就知道它将一直存在)。此外,您还可以传入整个
unique_ptr
s,因为它完全可以使用移动构造函数


所以说真的,在抛出异常之前,你没有正确地将非RAII对象(int*
)包装到RAII对象中,这是你的错。

Ah——但该对象从未进入。定位在向量内存块本身内部构建对象。传入的是指针,而不是
唯一\u ptr
。当然,指针被销毁了,但是我能保证
unique\u ptr
的析构函数运行并删除指针吗?实际上
模板
对于异常来说是不可操作的,这说明
int
没有正确地获取
delete
d,因为它的分配完全发生在
位置的外部
,而(解除分配)智能指针的构造发生在.Erm内部,从什么时候开始需要在此处分配“错误”?至于有“完全安全”的方法来做到这一点,当然,也有“安全”的方法来做到这一点。但是,如果你强制使用移动构造函数,你也可以使用
push_back
,因为它在所有情况下都强制执行正确的行为。@BillyONeal:至于“fault”,你建议应该“禁止”(不管是什么意思)。这意味着您认为语言/API是错误的,应该避免使用。因此,如果您遇到这个问题,那是语言/API的错,而不是程序员的错。如果只是用户错误,没有理由禁止它,对吗?@Nicol:Hmm。。。不是我所说的禁止。让我们说“强烈劝阻”。好的观点。这促使我放弃使用
new
,完全支持
std::make_unique
,这样我就可以从一开始就知道每一次分配都以一个智能指针结束。我在这里的评论中指出了这个陷阱: