Noexcept有什么用? [英] What is noexcept useful for?

查看:421
本文介绍了Noexcept有什么用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我看到 C ++ 11 添加了 noexcept 关键字。但是我真的不明白为什么它有用。

I saw that C++ 11 added the noexcept keyword. But I don't really understand why is it useful.

如果函数在不应该抛出的时候就抛出了-为什么我希望程序崩溃?

If the function throws when it's not supposed to throw - why would I want the program to crash?

那么我什么时候应该使用它?

So when should I use it?

此外,它如何与/ Eha一起编译并使用 _set_se_translator ?这意味着任何代码行都可以引发c ++异常-因为它可能会引发SEH异常(由于访问受保护的内存),并将其转换为c ++异常。

Also, how will it work along with compiling with /Eha and using _set_se_translator? This means that any line of code can throw c++ exception - because it might throw a SEH exception (Because of accessing protected memory) and it will be translated to c++ exception.

推荐答案

noexcept 的主要用途是通用算法,例如,在调整 std :: vector< T> 的大小时:为了有效地移动元素,必须提前知道没有动作会抛出。如果移动的元素可能会抛出,则需要复制元素。使用 noexcept(expr)运算符,库实现可以确定是否可能抛出特定操作。不抛出操作的属性成为合同的一部分:如果违反了该合同,则所有赌注都将取消,并且可能无法恢复有效状态。自然而然地选择了保全。

The primary use of noexcept is for generic algorithms, e.g., when resizing a std::vector<T>: for an efficient algorithm moving elements it is necessary to know ahead of time that none of the moves will throw. If moving elements might throw, elements need to be copied instead. Using the noexcept(expr) operator the library implementation can determine whether a particular operation may throw. The property of operations not throwing becomes part of the contract: if that contract is violated, all bets are off and there may be no way to recover a valid state. Bailing out before causing more damage is the natural choice.

要传播有关 noexcept 操作的知识,请不要丢掉它。也需要这样声明函数。为此,您可以使用 noexcept throw() noexcept(expr )和一个常量表达式。实现通用数据结构时,使用表达式的形式是必需的:使用该表达式,可以确定任何类型相关的操作是否可能引发异常。

To propagate knowledge about noexcept operations do not throw it is also necessary to declare functions as such. To this end, you'd use noexcept, throw(), or noexcept(expr) with a constant expression. The form using an expression is necessary when implementing a generic data structure: with the expression it can be determined whether any of the type dependent operations may throw an exception.

例如, std :: swap()声明如下:

template <typename T>
void swap(T& o1, T& o2) noexcept(noexcept(T(std::move(o1)) &&
                        noexcept(o1 = std::move(o2)));

基于 noexcept(swap(a,b))然后,库可以选择某些操作的不同有效实现:如果它可以 swap()而不会冒例外的危险,则它可能会暂时违反不变式并在以后恢复它们。如果可能引发异常,则库可能需要复制对象而不是移动对象。

Based on noexcept(swap(a, b)) the library can then choose differently efficient implementations of certain operations: if it can just swap() without risking an exception it may temporarily violate invariants and recover them later. If an exception might be thrown the library may instead need to copy objects rather than moving them around.

标准C ++库实现不太可能依赖于许多操作来实现是 noexcept(true)。它可能要检查的操作主要是与移动对象有关的操作,即:

It is unlikely that the standard C++ library implementation will depend on many operations to be noexcept(true). The probably the operations it will check are mainly those involved in moving objects around, i.e.:


  1. 一个类的析构函数(请注意,即使没有任何声明,默认情况下析构函数也是 noexcept(true);如果您具有可能抛出,您需要这样声明它,例如: T ::〜T()noexcept(false))。

  2. 移动运算符,即move构造( T :: T(T&&))和移动分配( T :: operator =(T&))
  3. 类型的 swap()操作( swap(T& ;, T& )以及成员版本 T :: swap(T&))。

  1. The destructor of a class (note that destructors are by default noexcept(true) even without any declaration; if you have destructor which may throw, you need to declare it as such, e.g.: T::~T() noexcept(false)).
  2. The move operators, i.e. move construction (T::T(T&&)) and move assignment (T::operator=(T&&)).
  3. The type's swap() operations (swap(T&, T&) and possibly the member version T::swap(T&)).

如果这些操作中的任何一个偏离默认值,则应相应地声明它以获得最有效的实现。这些操作的生成版本根据用于成员和基础的相应操作声明它们是否引发异常。

If any of these operations deviates from the default you should declare it correspondingly to get the most efficient implementation. The generated versions of these operations declare whether they are throwing exceptions based on the respective operations used for members and bases.

尽管我可以想象可能会在其中添加一些操作将来或某些特定的库,我现在可能不会将操作声明为 noexcept 。如果出现了其他功能,而这些功能的区别是 noexcept ,将来可以声明它们(并可以根据需要更改)。

Although I can imagine that some operations may be added in the future or by some specific libraries, I would probably not declaration operations as noexcept for now. If other functions emerge which make a difference being noexcept they can be declared (and possible changed as necessary) in the future.

这篇关于Noexcept有什么用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆