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

Why std::any & operator= for ValueType is not conditionally noexcept?

问题很简单

这是 std::any:

的模板化 operator= 声明
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 复制分配给 any,那么您应该能够拥有 noexcept。

也许我漏掉了什么。

字面上的答案是这样的规范是递归的(如果赋值是noexcept,你说的赋值应该是noexcept)。

但可能更有用的答案是,由于 any 可能必须分配,所以在 decay_t<ValueType>

的情况下,您只能真正进行 noexcept 分配
  • 足够小(以至于不需要分配),并且
  • 没有可构造的移动,并且
  • ValueType
  • 不抛出构造

指定 noexcept 条件的唯一方法是要求您还指定 "sufficiently small" 的含义 - 这会限制实施自由度,以获得可疑的收益。

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

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

[any.assign]/12 - Throws: Any exception thrown by the selected constructor of VT.

如果 ValueType 是可复制构造的,您显示的重载仅参与重载决策,这为 ValueType 的复制构造在 std::any 赋值期间抛出敞开大门。

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