当传递函数指针时,是否应该转发有关 noexcept 的知识?

7
我已经写了下面的代码来测试函数调用中的noexcept传递,但似乎它并没有像我想象的那样工作。 在GCC 4.7.2中,一个函数只有直接测试或作为模板特化参数传递时才能有效地被测试为noexcept;但是,在作为模板化函数的参数或普通函数的函数指针作为参数时,甚至当该函数声明其形式参数为noexcept时也不行。以下是代码:
#include <iostream>

#define test(f) \
    std::cout << __func__ << ": " #f " is " \
              << (noexcept(f()) ? "" : "not ") \
              << "noexcept\n";

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 不是 noexcept
主函数:f2 是 noexcept
test0: f 不是 noexcept
test0: f 是 noexcept
test1: f 不是 noexcept
test1: f 不是 noexcept
test2: f 不是 noexcept
test2: f 不是 noexcept
test3: f 不是 noexcept
test3: f 不是 noexcept
为什么在其他情况下没有传播 noexceptness?在 test1 的情况下,整个函数都使用适当的 F 类型 "实例化",编译器肯定知道 F 是否是 noexcept 函数。为什么可以按我编写 test3,当完全忽略 noexceptness 声明?
标准是否必须对此做出具体说明?
2个回答

6

C++11标准第15.4.13节指出,“异常说明不被认为是函数类型的一部分”。


3
在C++17中,noexcept终于被添加到类型系统中。指向非noexcept函数的指针不能隐式地转换为指向noexcept函数的指针。(但反过来是允许的)。
使用-std=c++1z的clang 3.9.0和-std=c++17的g++ 7.0会拒绝test3(f1);这一行代码。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接