是否应该在传递函数指针时转发关于noexcept-ness的知识?

时间:2012-12-22 14:05:33

标签: c++ c++11 noexcept

我已经编写了以下代码来测试noexcept跨函数调用的传播,似乎它没有像我想象的那样工作。在GCC 4.7.2中,只能直接或作为模板特化参数传递时,可以有效地测试函数noexcept;但是 not 作为参数传递给模板化函数,或者作为函数指向普通函数 - 即使该函数将其形式参数声明为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;
}

这是输出:

main: f1 is not noexcept
main: f2 is noexcept
test0: f is not noexcept
test0: f is noexcept
test1: f is not noexcept
test1: f is not noexcept
test2: f is not noexcept
test2: f is not noexcept
test3: f is not noexcept
test3: f is not noexcept

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

标准是否必须说明具体内容?

2 个答案:

答案 0 :(得分:6)

C ++ 11标准的第15.4.13节规定“异常规范不被视为函数类型的一部分”。

答案 1 :(得分:2)

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

使用-std=c++1z的3.9.0和使用-std=c++17的g ++ 7.0,拒绝该行test3(f1);