如果对象的构造函数不是except,可以放置new (expression)抛出

Can placement new (expression) throw if the constructor of the object is noexcept?

本文关键字:new expression 抛出 构造函数 对象 except 如果      更新时间:2023-10-16
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可以在分配失败或构造失败时抛出(如果有其他情况请纠正我),但是由于位置new不分配任何空间,如果T的构造函数不抛出,new表达式可以抛出吗?

。以下noexcept规格是否正确安全?

Obj(Args&&... args) noexcept(noexcept(T(std::forward<Args>(args)...))) {
  new (&value_pod_) T(std::forward<Args>(args)...);
}

根据18.6 [support]将<new>中的位置new声明为noexcept。动态]第1段:

void* operator new (std::size_t size, void* ptr) noexcept;

使用new表达式时,系统只做两件事:

  1. 调用相应版本的operator new()来获取内存。如果内存分配失败,它应该为没有noexcept资格的operator new()抛出std::bad_alloc,否则返回nullptr
  2. 如果返回非nullptr,则该表达式调用new表达式中该类型的构造函数。如果此构造失败并出现异常,则调用与被调用operator new()匹配的operator delete(),并使用该operator new()的结果。

由于内存分配不可能失败,获得异常的唯一选项是从该类型的构造函数