Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/visual-studio/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ noexcept的用途是什么?_C++_Visual Studio_Exception_C++11_Noexcept - Fatal编程技术网

C++ noexcept的用途是什么?

C++ noexcept的用途是什么?,c++,visual-studio,exception,c++11,noexcept,C++,Visual Studio,Exception,C++11,Noexcept,我看到C++11添加了noexcept关键字。但我真的不明白它为什么有用 如果函数在不应该抛出的时候抛出-为什么我希望程序崩溃 那我什么时候用呢 另外,它将如何与使用/Eha编译和使用\u set\u se\u translator一起工作?这意味着任何代码行都可以抛出C++异常——因为它可能抛出SEH异常(因为访问受保护的内存),并且它将被翻译成C++异常。 然后会发生什么?程序可能崩溃的原因是noexcept告诉优化器您的代码不会抛出。如果确实如此,那么就无法预测优化后的代码会发生什么 至于

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

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

那我什么时候用呢

另外,它将如何与使用/Eha编译和使用
\u set\u se\u translator
一起工作?这意味着任何代码行都可以抛出C++异常——因为它可能抛出SEH异常(因为访问受保护的内存),并且它将被翻译成C++异常。
然后会发生什么?

程序可能崩溃的原因是
noexcept
告诉优化器您的代码不会抛出。如果确实如此,那么就无法预测优化后的代码会发生什么


至于MSVC++,您必须检查当它们实现
noexcept
时会发生什么。从标准的观点来看,SEH是未定义的行为。访问受保护的内存现在可能已经崩溃。

noexcept的主要用途是用于通用算法,例如,在调整
std::vector
的大小时:对于移动元素的有效算法,必须提前知道所有移动都不会抛出。如果移动的元素可能会抛出,则需要复制元素。使用
noexcept(expr)
操作符,库实现可以确定特定操作是否可能抛出。不抛出的操作的属性成为合同的一部分:如果违反该合同,所有赌注都将被取消,并且可能无法恢复有效状态。在造成更多损害之前进行救援是自然的选择

要传播有关
noexcept
操作不抛出的知识,还需要声明函数本身。为此,您将使用带有常量表达式的
noexcept
throw()
noexcept(expr)
。在实现泛型数据结构时,使用表达式的表单是必需的:使用表达式可以确定是否有任何依赖类型的操作可能引发异常

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

template <typename T>
void swap(T& o1, T& o2) noexcept(noexcept(T(std::move(o1)) &&
                        noexcept(o1 = std::move(o2)));
模板
无效掉期(T&o1、T&o2)无例外(无例外(T(标准::移动(o1))&&
无异常(o1=标准::移动(o2));
基于
noexcept(swap(a,b))
库可以选择某些操作的不同高效实现:如果它可以
swap()
在不冒异常风险的情况下,它可能会暂时违反不变量,并在以后恢复它们。如果可能引发异常,则库可能需要复制对象,而不是移动对象

<标准> C++库的实现不太可能依赖于许多操作,除非是(真),否则它将被检查,主要是那些移动对象周围的操作,即:

  • 类的析构函数(请注意,即使没有任何声明,析构函数在默认情况下也是
    noexcept(true)
    ;如果您有可能抛出的析构函数,则需要将其声明为该析构函数,例如:
    T::~T()noexcept(false)
  • 移动运算符,即移动构造(
    T::T(T&&)
    )和移动赋值(
    T::operator=(T&&)
  • 类型的
    swap()
    操作(
    swap(T&,T&)
    ,可能还有成员版本
    T::swap(T&)
  • 如果这些操作中的任何一个偏离默认值,您应该相应地声明它以获得最有效的实现。这些操作的生成版本声明它们是否基于用于成员和基的相应操作引发异常


    虽然我可以想象将来可能会添加一些操作,或者由一些特定的库添加,但我现在可能不会将操作声明为
    noexcept
    。如果出现其他函数,它们可以声明(并根据需要进行更改)将来。

    您希望
    noexcept
    告诉系统函数不会抛出异常。如果它仍然抛出异常(因为某些开发人员是个白痴,要么直接抛出异常,要么在没有
    的情况下间接调用某个异常,请尝试
    -
    捕获它周围的
    块,很可能是这样),那么您认为系统应该怎么做?显然,如果您访问不允许访问的内存,您的代码将以某种方式崩溃,那么如果它以某种方式崩溃又有什么区别呢?我推荐以下帖子:程序甚至崩溃了吗?我的印象是
    std::terminate
    正在崩溃调用,这更像是“有序中止”,而不是崩溃(这基本上意味着也需要生成调用
    terminate
    的额外代码)。出于好奇:是什么使得SEH未定义行为?@MFH:简单地说,SEH没有出现在标准中,因此所有定义的行为都不是SEH。通过否定,所有SEH都不是定义的行为。UB的解释不会在标准中显式地呈现任何东西吗?例如,每个函数、类型、名称空间都写入-UB?如果您通过w从noexcept进入UB land,但SEH本身在默认情况下听起来并不一定像UB…@MFH:standard制定了规则。这些规则允许
    struct foo{int i_34568790845609;}
    即使特定的构造没有出现。但是,这些规则不可能允许SEH。一组构造是无限的这一事实并不意味着它包含所有内容。偶数的集合如果是无限的,但不包含3。@MSaltes:我不同意,但标准中的哪个规则呈现SEH的实施特定性质-注意,SEH不一定由UB产生,但也可以由软件发布(例如,在参数无效的情况下)。SEHs