C++17开使,throw()等价于noexcept。等等,throw(A,B,C)哪里去了?C++11时就被扔了。为什么?都被当垃圾扔了,还研究它干啥!
那可好了,只要研究好noexcept这一个“异常说明“就好,给学习C++的新人大大的松绑了。不用一边学习一边做语言的考古学家了。
考虑如下代码:
int add(int a,int b) noexcept { return a+b; }
异常说明(exception specification)是函数声明的一部分,它的重要性不亚于const。编译器可以依照noexcept做优化。
void may_throw(int arg) noexcept(false) //等价于void may_throw(int arg) { if (arg){ throw arg; } } void can_not_throw(int arg) noexcept //等价于void can_not_throw(int arg) noexcept(true) { }
nothrow(true) 程序员保证他/她写的程序不向外扔异常。如果让运行时系统逮到can_not_throw函数扔了异常出来,从而违反了约定怎么办?凉拌,当作违反断言assert一样的处理逻辑,既然让不符合逻辑的事情发生了,就立即终止程序吧。
nothrow(false) 有可能抛出异常,编译器需要插入一些异常处理相关的代码(绝不是catch这样简单的东西,涉及到unwind栈等复杂的东西)。
我们可以让编译器替我们决定异常说明的细节,例如:
void to_throw_or_not_to_throw(int arg) noexcept( noexcept(may_throw(0)) && noexcept(can_not_throw(0)) ) { may_throw(); can_not_throw(); }
简单的说,to_throw_or_not_throw函数的异常说明,由表达式noexcept(may_throw(0)) && noexcept(can_not_throw(0))的值决定。
noexcept(may_throw(0)) 运算符,返回may_throw函数是否是不抛异常的,同理noexcept(can_not_throw(0))。
算来算去,to_throw_or_not_to_throw还是可能抛异常的。因为bool ret = noexcept(may_throw(0)) && noexcept(can_not_throw(0)) == false
这意味着等价于void to_throw_or_not_to_throw(int arg) noexcept(false);