为什么ValueType的std :: any&operator =不是有条件的例外?

时间:2018-12-25 20:31:47

标签: c++ c++17 assignment-operator any noexcept

问题很简单。

这是std::any的模板化操作符=的声明:

template<typename ValueType>
any& operator=( ValueType&& rhs );

我希望它是:

template<typename ValueType>
any& operator=( ValueType&& rhs ) noexcept(noexcept(std::declval<std::any>() = std::forward<ValueType>(std::declval<ValueType>()));

也就是说,如果您可以以noexcept方式将ValueType复制-分配给任何类型,那么您应该可以拥有noexcept。

也许我错过了一些东西。

2 个答案:

答案 0 :(得分:6)

字面上的答案是,这样的规范将是递归的(如果分配是noexcept,则是指分配应该是noexcept)。

但是可能更有用的答案是,由于any可能不得不分配,因此,在noexcept为真的情况下,您只能真正分配decay_t<ValueType>

  • 足够小(以便不需要分配),并且
  • 没有动静的动作,并且
  • 不能从ValueType构造

指定noexcept条件的唯一方法是要求您还指定“足够小”的含义-这将限制实现自由,从而带来可疑的收益。

标准库通常不使用有条件的noexcept-那么为什么会是...例外?

答案 1 :(得分:1)

  

template<class T> any& operator=(T&& rhs);

     

[any.assign]/12 -引发:选定的VT构造函数引发的任何异常。

您显示的重载仅在ValueType是可复制构造的情况下才参与重载解析,这为ValueType的复制构造在std::any分配期间抛出打开了大门。

请注意,您还将显示根据定义的相同操作定义的noexcept规范。