为什么“noexcept”限定符不是函数类型的一部分?

21
我不明白为什么?我认为兼容性不应该是个问题,因为没有指定的函数实际上会隐式定义为false。如果是关于名称修饰的问题 - 我们可以假设旧的(已存在的)将意味着noexcept(false),并为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
你也可以有两个不同返回类型的重载 - 但是不允许这样做。这也不行。 - AnArrayOfFunctions
9
请参见已关闭的 CWG 问题#92 和 N4320。 - dyp
5
你应该把那个变成一个回答。 - Mark B
@Columbo 可能是这样,但更可能是 N4320 的结果吧? - dyp
@Columbo 由于我的评论和CWG问题下的新说明都来自2015年4月,因此我当时很可能没有看到它。 - dyp
显示剩余4条评论
2个回答

13

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

参考资料

noexcept指定符是函数类型的一部分,并且可以出现在任何函数声明符的一部分中。(自C++17起)


你能添加一个引用吗? - Peter - Reinstate Monica

3

C/C++03兼容性

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

低级别

让我们思考一下函数在低级别上是如何工作的。它们基本上是带有保存的(在堆栈上)返回地址的跳转。它们也通过堆栈传递参数和返回值(不总是这样,但让我们简化一下)。因此,当您声明一个函数时,实际上是告诉程序该函数应从堆栈中取出多少字节,并将其留在堆栈上。函数声明首先告诉程序通常从函数中期望什么。现在,知道了这一点,异常是否会改变通常从函数传递的信息?它们不会。我认为这是异常不是类型的主要原因。

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

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

这个决定背后的原因是,据我所知,为了更好的优化。

我不同意你在“低级”部分的推理,因为“const”并不会改变我们对函数的期望,并且它会导致新的重载。 - BigBoss
1
有许多实现需要调用可能会抛出异常的函数,这将要求编译器做比通常更多的工作,或者放弃本来可以进行的优化。如果函数指针总是指向一个将正常返回的函数,那么要求编译器悲观地假设它可能做其他事情是否有所收获?我可以看到通过noexcept指针允许调用未经noexcept限定的函数的方式对于要求编译器有益处... - supercat
1
在函数实际上并未抛出异常的情况下,它将具有定义行为,但我认为将指针分为具有或不具有noexcept限定符的不同但兼容类型没有任何不利影响。 - supercat

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接