C++03 throw() 说明符 C++11 noexcept 之间的区别

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12833241/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 16:39:55  来源:igfitidea点击:

Difference between C++03 throw() specifier C++11 noexcept

c++exceptionc++11thrownoexcept

提问by iammilind

Is there any difference between throw()and noexceptother than being checked at runtime and compile time, respectively?

有什么区别throw()noexcept其他比分别运行时和编译时,被检查?

This Wikipedia C++11 articlesuggests that the C++03 throw specifiers are deprecated.
Why so, is noexceptcapable enough to cover all that at compile time ?

这篇维基百科 C++11 文章表明 C++03 抛出说明符已被弃用。
为什么这样,有noexcept能力在编译时涵盖所有内容?

[Note: I checked this questionand this article, but couldn't determine the solid reason for deprecation.]

[注意:我检查了这个问题这篇文章,但无法确定弃用的确切原因。]

回答by Nicol Bolas

Exception specifiers were deprecated because exception specifiers are generally a terrible idea. noexceptwas added because it's the one reasonably useful use of an exception specifier: knowing when a function won'tthrow an exception. Thus it becomes a binary choice: functions that will throw and functions that won't throw.

异常说明符已被弃用,因为异常说明符通常是一个糟糕的主意noexcept添加是因为它是异常说明符的一个相当有用的用法:知道函数何时不会抛出异常。因此它变成了一个二元选择:会抛出的函数和不会抛出的函数。

noexceptwas added rather than just removing all throw specifiers other than throw()because noexceptis more powerful. noexceptcan have a parameter which compile-time resolves into a boolean. If the boolean is true, then the noexceptsticks. If the boolean is false, then the noexceptdoesn't stick and the function may throw.

noexcept添加而不是仅仅删除所有抛出说明符,throw()因为noexcept更强大。noexcept可以有一个编译时解析为布尔值的参数。如果布尔值是真的,那么noexcept棒。如果布尔值为假,则noexcept不会粘住,函数可能会抛出。

Thus, you can do something like this:

因此,您可以执行以下操作:

struct<typename T>
{
  void CreateOtherClass() { T t{}; }
};

Does CreateOtherClassthrow exceptions? It might, if T's default constructor can. How do we tell? Like this:

是否CreateOtherClass抛出异常?它可能,如果T的默认构造函数可以。我们怎么讲?像这样:

struct<typename T>
{
  void CreateOtherClass() noexcept(is_nothrow_default_constructible<T>::value) { T t{}; }
};

Thus, CreateOtherClass()will throw iff the given type's default constructor throws. This fixes one of the major problems with exception specifiers: their inability to propagate up the call stack.

因此,CreateOtherClass()当给定类型的默认构造函数抛出时,将抛出。这解决了异常说明符的主要问题之一:它们无法向上传播调用堆栈。

You can't do this with throw().

你不能用throw().

回答by CB Bailey

noexceptisn't checked at compile time.

noexcept编译时不检查。

An implementation shall not reject an expression merely because when executed it throws or might throw an exception that the containing function does not allow.

实现不应仅仅因为表达式在执行时抛出或可能抛出包含函数不允许的异常而拒绝表达式。

When a function that is declared noexceptor throw()attempts to throw an exception the only difference is that one calls terminateand the othe calls unexpectedand the latter style of exception handling has effectively been deprecated.

当一个函数被声明noexceptthrow()试图抛出异常时,唯一的区别是一个调用terminate和另一个调用unexpected以及后者的异常处理风格已​​被有效地弃用。

回答by ma13

std::unexpected()is called by the C++ runtime when a dynamic exception specification is violated: an exception is thrown from a function whose exception specification forbids exceptions of this type.

std::unexpected()当违反动态异常规范时由 C++ 运行时调用:从其异常规范禁止此类异常的函数抛出异常。

std::unexpected()may also be called directly from the program.

std::unexpected()也可以直接从程序中调用。

In either case, std::unexpectedcalls the currently installed std::unexpected_handler. The default std::unexpected_handlercalls std::terminate.

无论哪种情况,都会std::unexpected调用当前安装的std::unexpected_handler. 默认std::unexpected_handler调用std::terminate.