C++ 如果对象的构造函数是noexcept,placement new(expression)能否抛出?

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(),并使用该运

根据18.6[支持.动态]第1段,将
中的
位置声明为
无异常

<代码>无效*运算符新(标准::大小\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)...);
    }