c++ - 如果对象的构造函数是noexcept,placement new(expression)可以抛出吗?

标签 c++ exception c++11 placement-new noexcept

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 系统恰好做了两件事:

  1. 它调用适当版本的operator new()以获得内存。如果内存分配失败,它应该抛出 std::bad_alloc对于 operator new()没有 noexcept资格与返回nullptr否则。
  2. 如果非nullptr被返回,表达式然后调用 new 中类型的构造函数表达。如果此构造因异常而失败,则 operator delete()匹配调用的 operator new()operator new() 的结果调用.

由于内存分配不会失败,因此获得异常的唯一选择是来自类型的构造函数。

关于c++ - 如果对象的构造函数是noexcept,placement new(expression)可以抛出吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24266375/

相关文章:

c++ - 尽管有足够的空间,CListCtrl 仍显示省略号(仅限 Win2008 和 Win7)

c++ - 给定整数 n 决定是否可以将其表示为两个整数的平方和

c++ - 声明未知维度的二维数组的最佳方法是什么?

c++ - C++ 类函数能否判断自上次调用以来类成员对外部类的引用是否已更新?

c++ - 将许 multimap 像保存为 vector 但它们不显示

c++ - 是否可以防止此代码出现 "copy and paste similar template special case"?

java - catch block 中除以零时不会引发异常

android - 从 Android 设备发送 HTTPS/HTTP POST 时出现 UnknownHostException

java - 已检查未检查异常

c++ - 什么时候在空实例上调用成员函数会导致 C++11 中的未定义行为?