为什么 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
规范。
问题很简单
这是 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 复制分配给 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
规范。