noexcept 成为类型系统的一部分

noexcept to become part of the type system

我听说 noexcept 将成为 C++17 中函数类型的一部分。这会有什么不同?这是否意味着我们必须在模板中区分 noexcept 和非 noexcept 函数和成员函数(这将使我们必须编写的样板代码量加倍)?

例如,对于匹配函数指针的当前模板:

template<typename R, typename... Args>
struct Foo<R (*)(Args...)> {};

我们还需要一个:

template<typename R, typename... Args>
struct Foo<R (*)(Args...) noexcept> {};

这仅适用于良好的旧功能。对于成员函数,我们已经有了 constvolatile 和 ref-qualifiers,产生了大量的组合。添加 noexcept 它会变得两倍糟糕。

如果他们盲目地改变一些东西,使 noexcept 限定条件成为函数指针类型的一部分,他们就会破坏大量代码,无论是通用的还是非通用的。因此,有一个后门。

In accord with P0021R1,任何指向 noexcept 限定函数的指针都可以隐式转换为指向非 noexcept 限定函数的指针。指向具有此类限定条件的成员函数的指针也是如此。

的确,建立这个漏洞似乎是提案中大约 2/3 语言的目的。

除了@NicolBolas 的回答,我想指出的是给定两个专业:

// 1
template<typename R, typename... Args>
struct Foo<R (*)(Args...)> {};

// 2
template<typename R, typename... Args>
struct Foo<R (*)(Args...) noexcept> {};

然后 Foo<decltype(fun)> 将匹配

的第一个
int fun1(int) {}

第二个

int fun2(int) noexcept {}

还给出了两个重载(不言而喻,我们将能够在异常规范上重载,因为这 将改变参数的类型 ):

int foo(int (*a)(int)); // 1
int foo(int (*a)(int) noexcept); // 2

编译器将为 fun1 选择第一个重载,为 fun2

选择第二个重载