noexcept作用于多operator()重载的函数对象始终返回true问题
问题解答
你遇到的现象本质是对noexcept运算符的作用对象存在误解,代码中的noexcept(vis1)并没有检查visitor实例的operator()重载的异常属性,相关解答如下:
问题1解答
noexcept(expr)的核心作用是判断表达式expr本身的求值过程是否会抛出异常,和表达式对应值的后续调用行为完全无关。
你代码中noexcept的操作数是vis1:这是一个已经完成初始化的左值对象,对这个标识符的求值只是取它的左值引用,没有任何运行时操作,也不会触发operator()的重载决议,自然也和不同operator()重载的noexcept属性没有任何关联,所以编译器可以直接给出唯一的判定结果。
补充说明:如果要检查某个operator()重载的异常属性,需要写完整的调用表达式,例如noexcept(vis1(0))才会触发int参数重载的异常属性检查,这时候才会用到重载决议逻辑。
问题2解答
正因为noexcept(vis1)的操作数只是单纯的左值取值操作,这个过程不会执行任何可能抛出异常的代码,按照C++标准的noexcept判定规则,该表达式的求值过程无异常抛出可能,所以返回结果为true。
这个结果和组成visitor的lambda的operator()有没有声明noexcept没有任何关系:因为此时根本没有调用任何lambda的调用运算符,lambda的异常属性不会被纳入判定逻辑。
验证示例
你可以将代码中noexcept的操作数改为调用表达式,就能得到符合你预期的结果:
// 检查int参数重载的异常属性,输出false constexpr auto isNoExcept = noexcept(vis1(0));
内容的提问来源于stack exchange,提问作者Matthias Grün
相关产品推荐
相关产品推荐

