用于函数对象的noexcept运算符总是产生true
我noexcept在尝试实现我自己的std::visit用于教育目的的版本时与操作员一起玩时偶然遇到了这个问题。这是仅包含相关部分的代码:
#include <iostream>
template<typename... Ts>
struct visitor : Ts... { using Ts::operator()...; };
template<typename... Ts>
visitor(Ts...) -> visitor<Ts...>;
int main() {
auto vis1 = visitor {
[](int s) {
},
[](double s) {
}
};
constexpr auto isNoExcept = noexcept(vis1);
std::cout << std::boolalpha << isNoExcept << 'n';
return 0;
}
这总是true为我输出(gcc 和 clang)。
我有两个问题:
noexcept当有多个operator()s 时,如何应用运算符,因为有些可能是noexcept,而有些则不是?怎么可能只有一个答案?这里究竟发生了什么?- 为什么这会返回
true,即使没有声明任何 lambda 表达式noexcept?
回答
在noexcept(vis1)您要检查的表达式中是vis1。这个表达式的计算不可能抛出异常,因为它不做任何事情。因此,true无论vis1.
但是,如果您编写noexcept(vis1(42)),则您正在检查评估表达式是否vis1(42)可能引发异常。由于采用 an 的重载int未标记noexcept,因此评估可能确实抛出异常,并且返回false。
要回答您的具体问题,
noexcept当有多个operator()s时,如何应用运算符?
您不应该一次noexcept在所有operator()s上应用运算符,而应该一次只对一个特定的s 应用,operator()如我上面所示,在这种情况下,编译器只检查是否标记了要选择的重载noexcept。