标签: noexcept

为什么STL容器中的swap成员函数没有声明为noexcept?

N3797开始,swap除非另有说明,否则C++标准要求容器函数不抛出任何异常[container.requirements.general](23.2.1§10).

  • 为什么swap指定的成员函数不抛出未声明noexcept

同样的问题适用于专门的非成员swap重载.

c++ swap noexcept c++11

13
推荐指数
2
解决办法
506
查看次数

如果类型为noexcept,C++ 11 STL中的哪些算法和容器可以更快?

关于使用noexcept需要多少关注的问题,正在进行一场辩论.我们都知道noexcept对于编译器的优化器并没有真正做大量的事情,除了外部定义的代码,编译器否则必须假设它可以抛出,因为它无法知道它的实现,因此标记事物的唯一真正的其他性能优势noexcept用于使用std :: move_if_noexcept <>的代码,假定它主要是STL容器及其算法.

因此,该评估将是这样的:你不能使用noexcept,除非:

  1. extern函数和类,其中编译器不知道可调用的实现.

  2. 移动构造函数,移动赋值运算符并交换可能包含在STL容器中的任何类型.

  3. 否则不要担心.

这是一个公平的评估吗?STL中还有其他地方可以产生更优化的代码吗?如果是这样,哪个STL实现是这个,什么需要标记为no,除了它工作,以及什么性能的好处导致(更少的内存分配,更低的复杂性)?

编辑:使CashCow建议更改措辞.

c++ algorithm stl noexcept c++11

13
推荐指数
1
解决办法
587
查看次数

C++ noexcept用于不抛出异常的函数,但可能导致内存故障

例如,有两种不同的方法来访问私有数组的元素,重载数组下标运算符或定义at:

T& operator[](size_t i) { return v[i]; }
T const& operator[](size_t i) const { return v[i]; }

T& at(size_t i)
{
     if (i >= length)
         throw out_of_range("You shall not pass!");

     return v[i];
}

T const& at(size_t i) const
{
     if (i >= length)
         throw out_of_range("You shall not pass!");

     return v[i];
}
Run Code Online (Sandbox Code Playgroud)

at版本可以抛出异常,但数组下标运算符不能.

我的问题是,尽管operator[]没有抛出异常,它是否可以被标记为noexcept甚至知道它可以引发SIGSEGV信号,还是只是一种不好的做法?

我想指出一个信号(如SIGSEGV)也不例外.作为文字解释noexcept意义,一个noexcept功能是声称它不会抛出异常.它什么也没说(包括信号).

但是,noexcept函数具有更多的意义,至少对于我的代码的客户而言.noexcept也隐含地说这个函数是安全的,它会在没有计算错误的情况下完成它的执行.

那么,标记noexcept一个不安全的功能是不合适的呢?

c++ noexcept

13
推荐指数
1
解决办法
770
查看次数

为什么在C++ 11/14中没有std :: move_if_noexcept对应std :: forward?

我曾经看过斯科特迈尔斯上GoingNative2013谈话'的有效C++ 11月14日采样器’,并解释说,他使用的std::move_if_noexcept.

所以我认为还应该std::forward_if_noexcept保证例外安全forward吗?为什么标准库中没有这样的内容?还有其他可能保证吗?

c++ noexcept perfect-forwarding c++11

12
推荐指数
1
解决办法
649
查看次数

noexcept,继承构造函数和无效使用实际完成的不完整类型

我不确定这是GCC编译器的错误还是预期的行为noexcept.
请考虑以下示例:

struct B {
    B(int) noexcept { }
    virtual void f() = 0;
};

struct D: public B {
    using B::B;
    D() noexcept(noexcept(D{42})): B{42} { }
    void f() override { }
};

int main() {
    B *b = new D{};
}
Run Code Online (Sandbox Code Playgroud)

如果noexcept删除它,它编译.
无论如何,正如在例子中,我从GCC v5.3.1得到了这个错误:

test.cpp:8:31: error: invalid use of incomplete type ‘struct D’
     D() noexcept(noexcept(D{42})): B{42} { }
                               ^
Run Code Online (Sandbox Code Playgroud)

据我所知,struct D不是一个不完整的类型,但继承构造函数涉及到语句,看起来编译器实际上考虑的是基本结构的完整性而B不是D.

这是预期的行为还是合法代码?

为清楚起见:

c++ language-lawyer noexcept c++11 inheriting-constructors

12
推荐指数
1
解决办法
442
查看次数

不扔是零成本的时候,noexcept 是不是没用?

noexcept如果您的实现具有零成本(如果没有抛出)异常模型,说明符是否无用?什么是缺乏noexcept有后果的例子?

c++ compilation exception noexcept

12
推荐指数
1
解决办法
155
查看次数

C++ 11 noexcept限定符和内联方法

当C++ 11 inline调用使用noexcept限定符声明的其他函数时,C++ 11是否对函数或方法提供任何保证?

class My_String { ...

    const char * c_str () const noexcept;
    inline operator const char * () const { return c_str(); }
};
Run Code Online (Sandbox Code Playgroud)

我假设优化编译器可以自由地实现内联方法,而没有完整的EH和堆栈展开,根据noexcept资格.我也希望这也是一个简单的访问方法:

... inline operator const char * () const { return m_buffer; }
Run Code Online (Sandbox Code Playgroud)

虽然这个例子看起来微不足道,但异常保证在用于实现其他类或函数时很重要.问: C++ 11标准是否解决了这个问题,还是应该标记内联方法noexcept?或者noexcept除非需要匹配类或函数规范,否则最好省略?

编辑:为避免一些混淆:noexcept内联方法是隐式的吗?

c++ inline exception noexcept c++11

11
推荐指数
1
解决办法
1702
查看次数

我应该声明我的异常noexcept的拷贝构造函数吗?

更有效的C++中,Scott Meyers说

C++指定复制作为异常抛出的对象.

我想,如果复制构造函数依次抛出异常,std::terminate则会调用,所以这是声明所有异常的复制构造函数的一个很好的理由noexcept(而且,我想,不要抛出从堆中分配内存的对象,喜欢std::string).

然而,我惊讶地发现GCC 4.7.1附带的标准库实现没有为std::bad_alloc和定义那些复制构造函数std::exception.他们不应该定义它们noexcept吗?

c++ exception copy-constructor noexcept c++11

11
推荐指数
1
解决办法
1666
查看次数

如何为noexcept函数指针创建别名?

我想这样做:

using function_type = void (*)(void*)noexcept;
Run Code Online (Sandbox Code Playgroud)

但是我收到错误"类型别名中不允许出现异常规范." (Xcode 6.1版中的clang)

有没有使用noexcept说明符创建别名的解决方法?

我正在寻找一些适用于跨平台功能的语言(不是扩展)定义的东西.

c++ function-pointers noexcept c++11

11
推荐指数
3
解决办法
1340
查看次数

Noexcept和copy,移动构造函数

在我看来,似乎是协议,当移动构造函数为noexcept(false)时,标准库必须调用复制构造函数而不是移动构造函数.

现在我不明白为什么会这样.此外,Visual Studio VC v140和gcc v 4.9.2似乎也有不同的做法.

我不明白为什么除了这是例如矢量的关注.我的意思是如果T没有,vector :: resize()应该如何能够提供强大的异常保证.正如我所看到的那样,矢量的异常级别将取决于T.无论是否使用复制或移动.我理解noexcept只是对编译器进行异常处理优化的眨眼.

当使用Visual Studio编译时,这个小程序在使用gcc编译时调用复制构造函数并移动构造函数.

include <iostream>
#include <vector>

struct foo {
  foo() {}
  //    foo( const foo & ) noexcept { std::cout << "copy\n"; }
  //    foo( foo && ) noexcept { std::cout << "move\n"; }
  foo( const foo & )  { std::cout << "copy\n"; }
  foo( foo && )  { std::cout << "move\n"; }

  ~foo() noexcept {}
};

int main() {
    std::vector< foo > v;
    for ( int i = 0; …
Run Code Online (Sandbox Code Playgroud)

c++ noexcept c++11

11
推荐指数
2
解决办法
3851
查看次数