为什么不是函数类型的“noexcept”说明符部分?

时间:2015-04-07 13:30:49

标签: c++ language-lawyer c++14 iso

我不知道为什么?我不认为兼容性应该是一个问题,因为在没有说明符的情况下声明的函数实际上将其隐式定义为false。如果它是关于名称修改的 - 我们可以假设旧的(现有的)将暗示noexcept(false)并将另一个新符号添加到mangling for noexcept(true)。

这在使用模板时会很有用,因为现在比较函数类型和noexcept说明符应该单独进行。我的基本含义是:

int func() noexcept(true), func_1() noexcept(false);

decltype(func) == decltype(func_1); //this now equals true

但另一方面,如果我们通过使用指针或引用来进行函数赋值,则会检查noexcept说明符,就好像它是类型的一部分:

int (&refFunc)() noexcept(true) = func_1; //target exception specification is not superset of source

int (&refFunc)() noexcept(true) = func; //ok

所以现在实现完整的功能匹配应该通过执行类型和noexcept检查来完成,这有点复杂:

decltype(func) == decltype(func_1) && noexcept(func()) == noexcept(func_1()); //this now equals false

想象一下,如果函数有参数:

int func(int, double) noexcept(true), func_1(int, double) noexcept(false);

decltype(func) == decltype(func_1) && noexcept(func(int{}, double{})) == noexcept(func_1(int{}, double{})); //this now equals false

2 个答案:

答案 0 :(得分:11)

从C ++ 17开始,noexcept说明符是函数类型的一部分。

Reference

  

noexcept-specification是函数类型的一部分,可以   作为任何函数声明符的一部分出现。 (自C ++ 17起)

答案 1 :(得分:3)

C / C ++ 03兼容性

最重要的C ++基本思想之一是向后兼容C语言和较旧的C ++版本。它适用于大多数情况。向函数说明符添加异常将否定这一想法。 C ++ 03和C中没有noexcept,它会导致函数指针等问题。

低级别

让我们想一想功能如何在低级别工作。它们基本上都是保存(在堆栈上)返回地址。它们也通过堆栈传递参数并返回值(并非总是如此,但让我们简化一下)。因此,当您声明一个函数时,您实际上会告诉函数应该从堆栈中获取多少字节,以及它留下多少字节。函数声明最重要的是告诉程序从函数到EXPECT NORMALLY的内容。现在,知道这一点,异常会改变通常传递给/从函数传递的信息中的任何内容吗?他们没有。而且我认为这是异常不属于类型的主要原因。

编辑:

在C ++ 17中noexcept实际上成为了类型系统的一部分,所以你不能这样做:

void (*p)();
void (**pp)() noexcept = &p; //error here

根据我所知,这一决定背后的理由是允许更好的优化。