首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

dynamic exception specification

列出函数可能直接或间接抛出的异常。

句法

throw( )

?

(deprecated in c++11)

throw(typeid, typeid, ...)

?

(deprecated in C++11)(until C++17)

1) Non-throwing dynamic exception specification

(until C++17)

1) Same as noexcept(true)

(since C++17)

2%29显式动态异常规范

此规范只能出现在函数、变量或非静态数据成员(其类型为函数类型、指向函数类型的指针、函数类型的引用、成员函数类型的指针)的顶级%28的函数声明器或函数声明器上,直到C++17%29声明器。它可能出现在参数的声明符或返回类型的声明器上。

二次

代码语言:javascript
复制
void f() throw(int); // OK: function declaration
void (*fp)() throw (int); // OK: pointer to function declaration
void g(void pfa() throw(int)); // OK: pointer to function parameter declaration
typedef int (*pf)() throw(int); // Error: typedef declaration

二次

解释

如果函数是用类型声明的T在其异常规范中列出的函数可能引发该类型的异常或由此派生的类型。

不完全类型、指针或对cv以外的不完整类型的引用。void*,并且在异常规范中不允许使用rvalue引用类型。如果使用数组和函数类型,则调整为相应的指针类型。参数包自C++11%29开始允许%28。

如果函数抛出其异常规范中未列出的类型的异常,则函数std::unexpected叫做。默认函数调用std::terminate,但是它可以被用户提供的函数%28via替换。std::set_unexpected%29可调用std::terminate或者抛出一个异常。如果抛出的异常std::unexpected异常规范接受,则堆栈展开将继续如常进行。如果是%27T,但是std::bad_exception是异常规范允许的,std::bad_exception被扔了。否则,std::terminate叫做。

Potential exceptions Each function f, pointer to function fp, and pointer to member function mfp has a set of potential exceptions, which consists of types that might be thrown. Set of all types indicates that any exception may be thrown. This set is defined as follows: 1) If the declaration of f, fp, or mfp uses throw()(deprecated) or noexcept, the set is empty. 2) Otherwise, if the declaration of f, fp, or mfp uses a dynamic exception specification(deprecated), the set consists of the types listed in that specification 3) Otherwise, the set is the set of all types Note: for implicitly-declared special member functions (constructors, assignment operators, and destructors) and for the inheriting constructors, the set of potential exceptions is a combination of the sets of the potential exceptions of everything they would call: constructors/assignment operators/destructors of non-variant non-static data members, direct bases, and, where appropriate, virtual bases (including default argument expressions, as always). Each expression e has a set of potential exceptions, defined as follows: 1) If e is a core constant expression, the set is empty 2) Otherwise, the set is the union of the sets of potential exceptions of all immediate subexpressions of e (including default argument expressions), combined with another set that depends on the form of e, as follows: 1) If e is a function call expression, and the function is named by an id-expression (either directly or as part of member access or pointer-to-member access expression), the set of potential exceptions of the named function is added to the list. if the function is named by an expression of type noexcept function or by an expression of type pointer to noexcept function, the set is empty otherwise, the set is the set of all types 2) If e calls a function implicitly (it's an operator expression and the operator is overloaded, it is a new-expression and the allocation function is overloaded, or it is a full expression and the destructor of a temporary is called)), then the set is the set of that function. 3) If e is a throw-expression, the set is the exception that would be initialized by its operand, or the set of all types for the re-throwing throw-expression (with no operand) 4) If e is a dynamic_cast to a reference to a polymorphic type, the set consists of std::bad_cast 5) If e is a typeid applied to a polymorphic glvalue, the set consists of std::bad_typeid 6) If e is a new-expression with a non-constant size, the set consists of std::bad_array_new_length void f() throw(int); // f()'s set is "int" void g(); // g()'s set is the set of all types struct A { A(); }; // "new A"'s set is the set of all types struct B { B() noexcept; }; // "B()"'s set is empty struct D() { D() throw (double); }; // new D's set is the set of all types All implicitly-declared member functions (and inheriting constructors) have exception specifications, selected as follows: If the set of potential exceptions is the set of all types, the implicit exception specification is noexcept(false). Otherwise, If the set of potential exceptions is not empty, the implicit exception specification lists every type from the set Otherwise, the implicit exception specification is noexcept(true) and the function type is "noexcept function" struct A { A(int = (A(5), 0)) noexcept; A(const A&) throw(); A(A&&) throw(); ~A() throw(X); }; struct B { B() throw(); B(const B&) = default; // exception specification is "noexcept(true)" B(B&&, int = (throw Y(), 0)) throw(Y) noexcept; ~B() throw(Y); }; int n = 7; struct D : public A, public B { int * p = new (std::nothrow) intn; // D has the following implicitly-declared members: // D::D() throw(X, std::bad_array_new_length); // D::D(const D&) noexcept(true); // D::D(D&&) throw(Y); // D::~D() throw(X, Y); };

(since C++17)

  • 该函数由id表达式%28直接命名,或作为成员访问或指针到成员访问表达式%29的一部分,命名函数的一组潜在异常将添加到列表中。
  • 如果该函数由no以外函数的表达式或指向no以外函数的类型指针的表达式命名,则该集合为空。
  • 否则,集合是所有类型的集合。

2%29e调用一个函数隐式%28 it%27 s为运算符表达式,且运算符重载,则为新表达式而分配函数是重载的,或者是一个完整的表达式,临时的析构函数被称为%29%29,那么这个集合就是该函数的集合。3%29e是抛出,则该集合是将由其操作数初始化的异常,或者是用于重新抛出抛出表达式%28的所有类型的集合,如果没有操作数%29 4%29,则为e是动态[医]铸造对于多态类型的引用,集合由std::bad_cast5%29e是类型应用于多态极值,该集合由std::bad_typeid6%29e是新表达式具有非常量大小的集合由std::bad_array_new_length空f%28%29抛出%28 int%29;//f%28%29%27s集是“int”空G%28%29;//g%28%29%27 s集是所有类型结构A{A%28%29;};///“新A”%27s集是所有类型结构B{B%28%29 Noo除外的集合;//“B%28%29”%27s集为空结构D%28%29{D%28%29抛出%28双%29};//新D%27s集是所有类型的集合

所有隐式声明的成员函数%28和继承构造函数%29都有异常规范,选择如下:

  • 如果潜在异常集是所有类型的集合,则隐式异常规范为noexcept(false)...
  • 否则,如果潜在异常集不是空的,则隐式异常规范将列出集合中的每个类型。
  • 否则,隐式异常规范是noexcept(true)函数类型为“除函数外”。

结构A{A%28int=%28A%285%29,0%29%29 no;A%28 const A&%29掷出%28%29;A%28A&%29掷出%28%29;~A%28%29掷出%28X%29;};结构B{B%28%29抛出%28%29;B%28 const B&%29=默认;//异常规格是“no除%28true%29 B%28B%28B&&,int=%28掷Y%28%29,0%29%29扔%28Y%29 noout;~B%28%29抛出%28Y%29;};INT n=7;结构D:public A,public B{int%2AP=新的%28 std::noput%29 intn//D有以下隐式声明的成员://D::d%28%29引发%28X,std::坏[医]列阵[医]新[医]长度%29;//D::d%28 const D&%29 no,除%28true%29;//D::d%28D&%29掷%28Y%29;//D:~D%28%29 pt%28X,Y%29;};

%28自C++17%29

二次

代码语言:javascript
复制
#include <iostream>
#include <exception>
#include <cstdlib>
 
class X {};
class Y {};
class Z : public X {};
class W {};
 
void f() throw(X, Y) 
{
    int n = 0;
    if (n) throw X(); // OK
    if (n) throw Z(); // also OK
    throw W(); // will call std::unexpected()
}
 
int main() {
  std::set_unexpected([]{
      std::cout << "That was unexpected" << std::endl; // flush needed
      std::abort();
  });
  f();
}

二次

产出:

二次

代码语言:javascript
复制
That was unexpected

二次

另见

  • noexcept说明符
代码语言:txt
复制
 ? cppreference.com

在CreativeCommonsAttribution下授权-ShareAlike未移植许可v3.0。

扫码关注腾讯云开发者

领取腾讯云代金券

http://www.vxiaotou.com