如何知道函数何时抛出以及何时使用noexcept

How to know when a function will throw and when to use noexcept

本文关键字:何时使 noexcept 何知道 函数 何时抛      更新时间:2023-10-16

在声明函数时,可以使用noexcept说明符来声明函数不会抛出:

int foo() noexcept
{
return 10;
}

然而,如何确定函数何时抛出?我知道使用new运算符可能会引发std::bad_alloc,但其他一些表达式/运算符会引发什么呢?有没有办法明确地确定它是否会这样做?

但是还有哪些其他表达式/运算符可以抛出?

潜在抛出表达式定义为(根据cppreference(

表达式e可能抛出if:

  • e是对潜在抛出函数或指向函数的指针的函数调用
  • e对潜在的抛出函数(例如重载运算符、新表达式中的分配函数、函数参数的构造函数,或者如果e是完整表达式则为析构函数(进行隐式调用
  • e是throw表达式
  • e是一个dynamic_cast,它强制转换多态引用类型
  • e是一个typeid表达式,应用于指向多态类型的取消引用指针
  • e有一个可能引发的立即子表达式

此外,任何具有未定义行为的表达式。

就语言而言,未声明为noexcept的函数可能会抛出,即使它可能永远不会抛出。

有没有办法明确确定它是否会?

通常情况下,不,您无法确定表达式是否会抛出-至少在假设p≠NP的多项式时间内不会。

但是,可以使用noexcept-表达式来确定表达式是否可能抛出

void foo() noexcept;
void bar() {
// nothing that might throw
}
std::cout << noexcept(1+1);                        // prints 1
std::cout << noexcept(foo())                       // prints 1
std::cout << noexcept(bar())                       // prints 0
std::cout << noexcept(new char);                   // prints 0
std::cout << noexcept(throw 1);                    // prints 0

没有办法确定每个函数是否会抛出异常(这至少与停止问题一样困难。但是,在某些情况下,您可以确信函数不会抛出异常。其中一个例子是一个常数函数返回10的琐碎例子。