当传递函数指针时,是否应该转发关于非例外性的知识?

Is knowledge about noexcept-ness supposed to be forwarded when passing around a function pointer?

本文关键字:非例外 知识 转发 指针 传递函数 是否      更新时间:2023-10-16

我已经编写了以下代码来测试跨函数调用的noexcept传播,并且似乎它不像我想象的那样工作。在GCC 4.7.2中,只有直接或作为模板专门化参数传递时,才能有效地测试函数是否为noexcept;但是当作为参数传递给模板函数时,或者作为普通函数的函数指针时,不能——即使该函数声明其形式形参为noexcept。下面是代码:

#include <iostream>
#define test(f) 
    std::cout << __func__ << ": " #f " is " 
              << (noexcept(f()) ? "" : "not ") 
              << "noexceptn";
template <void(*f)()>
static inline void test0() {
    test(f);
}
template <typename F>
static inline void test1(F f) {
    test(f);
}
static inline void test2(void(*f)()) {
    test(f);
}
static inline void test3(void(*f)()noexcept) {
    test(f);
}
void f1() {}
void f2() noexcept {}
int main() {
    test(f1);
    test(f2);
    test0<f1>();
    test0<f2>();
    test1(f1);
    test1(f2);
    test2(f1);
    test2(f2);
    test3(f1);
    test3(f2);
    return 0;
}

输出:

<>之前主:f1不是不例外Main: f2是不例外的Test0:不是noexceptTest0:不例外Test1:不是noexceptTest1:不是noexceptTest2:不是noexceptTest2:不是noexceptTest3:不是不例外Test3:不是不例外之前

为什么noexcept在其他情况下不传播?在test1的情况下,整个函数被"实例化"为F的适当类型,此时编译器肯定知道F是否为noexcept函数。当noexcept ness声明完全被忽略时,为什么可以按照我写的方式写test3 ?

标准对此有具体的规定吗?

c++ 11标准第15.4.13节声明"异常规范不被认为是函数类型的一部分"。

在c++ 17中,noexcept最终被添加到类型系统中。指向非noexcept函数的指针不能隐式转换为指向noexcept函数的指针。(但反过来也是允许的)。

clang 3.9.0 with -std=c++1z, g++ 7.0 with -std=c++17,拒绝test3(f1);