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?
}
}
Normal new
可以在分配失败或构造失败时抛出(如果有其他情况请纠正我),但由于 placement new 不分配任何空间,如果 T
的构造函数不抛出,新表达式是否会抛出?
即以下 noexcept
规范是否正确且安全?
Obj(Args&&... args) noexcept(noexcept(T(std::forward<Args>(args)...))) {
new (&value_pod_) T(std::forward<Args>(args)...);
}
最佳答案
展示位置 new
来自 <new>
声明为 noexcept
根据 18.6 [support.dynamic] 第 1 段:
...
void* operator new (std::size_t size, void* ptr) noexcept;
...
使用 new
时expression 系统恰好做了两件事:
- 它调用适当版本的
operator new()
以获得内存。如果内存分配失败,它应该抛出std::bad_alloc
对于operator new()
没有noexcept
资格与返回nullptr
否则。 - 如果非
nullptr
被返回,表达式然后调用new
中类型的构造函数表达。如果此构造因异常而失败,则operator delete()
匹配调用的operator new()
用operator new()
的结果调用.
由于内存分配不会失败,因此获得异常的唯一选择是来自类型的构造函数。
关于c++ - 如果对象的构造函数是noexcept,placement new(expression)可以抛出吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24266375/