我不知道为什么?我不认为兼容性应该是一个问题,因为在没有说明符的情况下声明的函数实际上将其隐式定义为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
答案 0 :(得分:11)
从C ++ 17开始,noexcept
说明符是函数类型的一部分。
noexcept-specification是函数类型的一部分,可以 作为任何函数声明符的一部分出现。 (自C ++ 17起)
答案 1 :(得分:3)
最重要的C ++基本思想之一是向后兼容C语言和较旧的C ++版本。它适用于大多数情况。向函数说明符添加异常将否定这一想法。 C ++ 03和C中没有noexcept
,它会导致函数指针等问题。
让我们想一想功能如何在低级别工作。它们基本上都是保存(在堆栈上)返回地址。它们也通过堆栈传递参数并返回值(并非总是如此,但让我们简化一下)。因此,当您声明一个函数时,您实际上会告诉函数应该从堆栈中获取多少字节,以及它留下多少字节。函数声明最重要的是告诉程序从函数到EXPECT NORMALLY的内容。现在,知道这一点,异常会改变通常传递给/从函数传递的信息中的任何内容吗?他们没有。而且我认为这是异常不属于类型的主要原因。
编辑:在C ++ 17中noexcept
实际上成为了类型系统的一部分,所以你不能这样做:
void (*p)();
void (**pp)() noexcept = &p; //error here
根据我所知,这一决定背后的理由是允许更好的优化。