7

我编写了以下代码来测试noexcept跨函数调用的传播,它似乎不像我想象的那样工作。在 GCC 4.7.2 中,可以有效地测试一个函数是否noexcept只被直接或作为模板特化参数传递;但在作为参数传递给模板化函数或作为指向普通函数的函数指针时不会——即使该函数将其形式参数声明为 is 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 不是 noexcept
main: 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函数。test3noexceptness声明被完全忽略时,为什么可以像我写的那样写?

标准是否必须对此进行具体说明?

4

2 回答 2

6

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

于 2012-12-22T15:19:00.460 回答
3

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

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

于 2016-12-22T23:06:51.910 回答