用于函数对象的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)。

我有两个问题:

  1. noexcept当有多个operator()s 时,如何应用运算符,因为有些可能是noexcept,而有些则不是?怎么可能只有一个答案?这里究竟发生了什么?
  2. 为什么这会返回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


以上是用于函数对象的noexcept运算符总是产生true的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>