>功能体?
>在可选的ctor-initializer中初始化成员?
>在可选的mem初始化器中初始化基类?
>在可选的mem初始化器中初始化类成员?
>复合语句?
> function-try-block?
>在ctor-initializer中未初始化对象基类的初始化?
>初始化对象类成员未初始化在ctor-initializer?
还有一些额外的东西
换句话说,如果noexcept(true)抛出异常,则noexcept noexcept-specification(即触发std :: terminate())包含以上哪一个?
解决方法
In other words,which of the above are encompassed by the
noexcept
noexcept-specification…?
异常规范(noexcept和动态异常规范)涉及构建基础类,构件和初始化成员以及构造函数体中的代码.基本上,在构造对象中执行的所有功能 – 这是有道理的,因为异常规范与对象的构造函数相关联,因此它应该涵盖在构造对象期间执行的代码;如果建筑的任何部分没有涵盖,这将是违反直觉的.
支持标准报价…
如果在施工期间抛出异常(可能未处理)怎么办?
Whenever an exception of type
E
is thrown and the search for a handler ([except.handle]) encounters the outermost block of a function with an exception specification that does not allowE
,then,
- if the function definition has a dynamic-exception-specification,the function
std::unexpected()
is called ([except.unexpected]),- otherwise,the function
std::terminate()
is called ([except.terminate]).
上述exception specification包括noexcept规范.
如何在隐式声明的构造函数中确定隐式声明的异常规范?
An implicitly-declared special member function
f
of some classX
is considered to have an implicit exception specification that consists of all the members from the following sets:
if
f
is a constructor,
the sets of potential exceptions of the constructor invocations
- for
X
‘s non-variant non-static data members,- for
X
‘s direct base classes,andif
X
is non-abstract ([class.abstract]),forX
‘s virtual base classes,(including default argument expressions used in such invocations) as selected by overload resolution for the implicit definition of f ([class.ctor])…
the sets of potential exceptions of the initialization of non-static data members from brace-or-equal-initializers that are not ignored ([class.base.init]);
这对编译器将用来确定(因此考虑覆盖)异常规范提供了非常有用的澄清.
1“功能的最外面的块”是什么意思?有人对对功能块的定义的关注发表了评论.该标准没有对函数块的正式定义.功能的短语块仅在Exception Handling [except]中使用.该短语从C 98开始就包含在标准中.
为了进一步明确,我们需要寻求替代来源并得出一些合理的结论.
function body – the outermost block of a function. See also: try-block,function definition. TC++PL 2.7,13.
从[dcl.fct.def.general]/1起,使用复合语句和function-try-block覆盖ctor-initializer的函数体的语法;
Function definitions have the form;
…
function-body:
ctor-initializeropt compound-statement
function-try-block…
Any informal reference to the body of a function should be interpreted as a reference to the non-terminal function-body…
同样重要的是要记住,异常规范与功能相关,而不是一般的代码块(作用域等).
给定异常处理子句和Stroustrup FAQ中的短语的年龄,函数的块与函数体相同,标准可能对异常子句中使用的语言进行更新.
给出以下代码的一些实证证据,用于构建a1,a2和a3(当其他人被注释掉)时,会导致std :: terminate被调用.结果适用于g++,clang和MSVC.
struct Thrower { Thrower() { std::cout << "throwing..." << std::endl; throw 42; } }; struct AsMember { Thrower t_; AsMember() noexcept : t_{} { std::cout << "ctor" << std::endl; } }; struct AsBase : Thrower { AsBase() noexcept { std::cout << "ctor" << std::endl; } }; struct AsNSDMI { Thrower t_ {}; AsNSDMI() noexcept { std::cout << "ctor" << std::endl; } }; int main() { std::set_terminate([](){ std::cout << "terminating..." << std::endl; }); try { //AsMember a1{}; //AsBase a2{}; AsNSDMI a3{}; } catch (...) { std::cout << "caught..." << std::endl; } return 0; }