C++ 如果对象的构造函数是noexcept,placement new(expression)能否抛出?
根据18.6[支持.动态]第1段,将C++ 如果对象的构造函数是noexcept,placement new(expression)能否抛出?,c++,exception,c++11,placement-new,noexcept,C++,Exception,C++11,Placement New,Noexcept,根据18.6[支持.动态]第1段,将中的新位置声明为无异常: 无效*运算符新(标准::大小\u t大小,无效*ptr)无例外 使用新的表达式时,系统只做两件事: 它调用适当版本的操作符new()以获取内存。如果内存分配失败,它应该为运算符new()抛出std::bad_alloc,而不带noexcept限定,否则返回nullptr 如果返回非nullptr,则表达式将调用new表达式中类型的构造函数。如果此构造因异常而失败,则调用与被调用的运算符new()匹配的运算符delete(),并使用该运
中的新
位置声明为无异常
:
<代码>无效*运算符新(标准::大小\u t大小,无效*ptr)无例外代码>
使用新的表达式时,系统只做两件事:
操作符new()
以获取内存。如果内存分配失败,它应该为运算符new()
抛出std::bad_alloc
,而不带noexcept
限定,否则返回nullptr
nullptr
,则表达式将调用new
表达式中类型的构造函数。如果此构造因异常而失败,则调用与被调用的运算符new()
匹配的运算符delete()
,并使用该运算符new()
的结果由于内存分配不能失败,因此获取异常的唯一选项是从类型的构造函数中获取。所有placement-
运算符new所做的是返回它传递的指针,因此不,placement new本身不能抛出。@Simple:placement new当然可以抛出,但只有当被构造的对象抛出其构造函数时,@Mankarse right,new
表达式作为一个整体才能,但是操作符new
没有。我对表达式整体感兴趣。您应该编辑您的问题以澄清这一点。我想问题是,新表达式是否除了调用构造函数之外还有其他功能。调用placement new的唯一功能是调用上面的操作符new()
然后在new
表达式中调用对象的构造函数(如果构造引发异常,它将调用匹配的运算符delete()
)。placement new表达式在调用构造函数之前还会检查运算符new
返回的地址是否与null ptr
一致。当然,在这种情况下,这不会有什么区别,但最好记住。如果传递给Obj::Obj
的实际参数需要用户定义的转换,这可能会抛出?@JamesKanze然后构造函数抛出……我想
template <class T>
struct Obj {
// Plain Old Data for T
using InternalPod = typename std::aligned_storage<sizeof(T), std::alignment_of<T>::value>::type;
InternalPod value_pod_;
template<class... Args>
Obj(Args&&... args) { // my constructor
// placement new: construct the value in the statically allocated space
new (&value_pod_) T(std::forward<Args>(args)...); // <- can this whole expression throw if the constructor of T doesn’t throw?
}
}
Obj(Args&&... args) noexcept(noexcept(T(std::forward<Args>(args)...))) {
new (&value_pod_) T(std::forward<Args>(args)...);
}