【问题标题】:Can placement new (expression) throw if the constructor of the object is noexcept?如果对象的构造函数是 noexcept,placement new (expression) 可以抛出吗?
【发布时间】:2014-08-07 14:48:40
【问题描述】:
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?
  }
}

正常 new 可以在分配失败或构造失败时抛出(如果有其他情况,请纠正我),但由于放置 new 不分配任何空间,new 表达式可以如果T 的构造函数不抛出就抛出?

即以下noexcept 规范是否正确且安全?

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

【问题讨论】:

  • 所有placement-operator new所做的只是返回它传递的指针,所以不,placement new 本身不能抛出。
  • @Simple: Placement new 当然可以抛出,但前提是正在构造的对象在其构造函数中抛出。
  • @Mankarse 对,new 表达式作为一个整体可以,但 operator new 不能。
  • 我对整个表达式感兴趣
  • 您应该编辑您的问题以澄清这一点。

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


【解决方案1】:

根据 18.6 [support.dynamic] 第 1 段,来自 &lt;new&gt; 的位置 new 被声明为 noexcept:

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

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

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

由于内存分配不能失败,唯一的选择是从类型的构造函数中获取异常。

【讨论】:

  • 我想问题是新表达式是否会做除了调用构造函数之外的任何其他事情
  • 调用placement new 所做的唯一事情是调用上面的operator new(),然后在new 表达式中调用对象的构造函数(如果构造抛出,它将调用匹配的operator delete()例外)。
  • placement new 表达式还在调用构造函数之前检查operator new 返回的地址和nullptr。当然,在这种情况下不会有什么不同,但记住这一点很好。
  • 如果传递给Obj&lt;T&gt;::Obj 的实际参数需要用户定义的转换,这可能会抛出?
  • @JamesKanze 然后构造函数抛出......我认为
猜你喜欢
  • 2013-08-22
  • 1970-01-01
  • 2021-08-22
  • 1970-01-01
  • 1970-01-01
  • 2012-04-23
  • 2015-10-17
  • 2011-05-01
  • 2017-01-28
相关资源
最近更新 更多