有什么能阻止 std::optional::value_or() 有条件地 noexcept 吗?
Does anything prevent std::optional::value_or() from being conditionally noexcept?
这是 C++17 标准中 value_or()
的定义:
template <class U> constexpr T value_or(U&& v) const&;
Effects: Equivalent to:
return bool(*this) ? **this : static_cast<T>(std::forward<U>(v));
Remarks: If is_copy_constructible_v<T> && is_convertible_v<U&&, T>
is false
, the program is ill-formed.
(右值重载类似)
value_or
的效果被描述为等同于return bool(*this) ? **this : static_cast<T>(std::forward<U>(v));
operator bool
是 noexcept
。 operator*
是 not noexcept
(即使它没有抛出,可能是因为如果在可选不包含值时使用它仍然会因 UB 而失败) .但是,我们保证永远不会尝试 return 包含的值,除非我们有一个。
所以不能 value_or
声明 noexcept
给定 is_nothrow_copy_constructible<T> && noexcept(static_cast<T>(std::forward<U>(v)))
?
noexcept is used extremely sparingly in the c++标准。这是唯一的障碍。
虽然这回答了问题,但下一个问题是“为什么很少使用它”。这是您可能会觉得有用的额外信息;如果这是答案的核心,我会包含更多引号而不是链接。纸质编号应该比我使用的特定超链接更有效,所以就是这样。
N3279 是关于 noexcept 的讨论的结论。基本上,任何具有窄合同(可以展示 UB)并且不是移动 ctor 或 dtor 的东西都不会被标记为 noexcept。
指南如下:
Adopted Guidelines
- No library destructor should throw. They shall use the implicitly supplied (non-throwing) exception specification.
- Each library function having a wide contract, that the LWG agree cannot throw, should be marked as unconditionally noexcept.
- If a library swap function, move-constructor, or move-assignment operator is conditionally-wide (i.e. can be proven to not throw by applying the noexcept operator) then it should be marked as conditionally noexcept. No other function should use a conditional noexcept specification.
- Library functions designed for compatibility with “C” code (such as the atomics facility), may be marked as unconditionally
noexcept.
我没有参与讨论,但基本想法是编译器可以向这些方法添加异常。
我相信这就是所谓的 Lakos 规则。要更改它,请与委员会讨论。
N3248 是提出 noexcept 问题的论文。主要是关于测试。
这是 C++17 标准中 value_or()
的定义:
template <class U> constexpr T value_or(U&& v) const&;
Effects: Equivalent to:
return bool(*this) ? **this : static_cast<T>(std::forward<U>(v));
Remarks: If
is_copy_constructible_v<T> && is_convertible_v<U&&, T>
isfalse
, the program is ill-formed.
(右值重载类似)
value_or
的效果被描述为等同于return bool(*this) ? **this : static_cast<T>(std::forward<U>(v));
operator bool
是 noexcept
。 operator*
是 not noexcept
(即使它没有抛出,可能是因为如果在可选不包含值时使用它仍然会因 UB 而失败) .但是,我们保证永远不会尝试 return 包含的值,除非我们有一个。
所以不能 value_or
声明 noexcept
给定 is_nothrow_copy_constructible<T> && noexcept(static_cast<T>(std::forward<U>(v)))
?
noexcept is used extremely sparingly in the c++标准。这是唯一的障碍。
虽然这回答了问题,但下一个问题是“为什么很少使用它”。这是您可能会觉得有用的额外信息;如果这是答案的核心,我会包含更多引号而不是链接。纸质编号应该比我使用的特定超链接更有效,所以就是这样。
N3279 是关于 noexcept 的讨论的结论。基本上,任何具有窄合同(可以展示 UB)并且不是移动 ctor 或 dtor 的东西都不会被标记为 noexcept。
指南如下:
Adopted Guidelines
- No library destructor should throw. They shall use the implicitly supplied (non-throwing) exception specification.
- Each library function having a wide contract, that the LWG agree cannot throw, should be marked as unconditionally noexcept.
- If a library swap function, move-constructor, or move-assignment operator is conditionally-wide (i.e. can be proven to not throw by applying the noexcept operator) then it should be marked as conditionally noexcept. No other function should use a conditional noexcept specification.
- Library functions designed for compatibility with “C” code (such as the atomics facility), may be marked as unconditionally noexcept.
我没有参与讨论,但基本想法是编译器可以向这些方法添加异常。
我相信这就是所谓的 Lakos 规则。要更改它,请与委员会讨论。
N3248 是提出 noexcept 问题的论文。主要是关于测试。