标签: noexcept

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
查看次数

如果执行受保护的基础构造函数是noexcept,我怎么能说"noexcept"?

我们有这种情况,并想知道解决它的最佳方法

template<typename T>
struct A : T {
  A(T &&t) noexcept(noexcept(T(std::move(t))))
     :T(std::move(t))
  { }
};
Run Code Online (Sandbox Code Playgroud)

遗憾的是,这无法编译,因为T的移动构造函数受到保护,我们只允许在构造函数初始化列表中调用它*this.有什么办法使这项工作或甚至有一个标准的方法呢?

c++ inheritance protected noexcept c++11

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

什么noexcept完全包含在构造函数中?

根据C++标准,类构造函数的noexcept noexcept-specification究竟适用于什么?

  1. 函数体
    1. 初始化可选的ctor-initializer中的成员?
      1. 在可选的mem-initializer s中初始化基类?
      2. 在可选的mem-initializer中初始化类成员?
    2. 复合语句
    3. 功能试块
  2. 初始化未在ctor-initializer中初始化的对象基类?
  3. 初始化未在ctor-initializer中初始化的对象类成员?
  4. 额外的东西?

换句话说,noexcept noexcept规范包含了上述哪一项(例如,std::terminate()在抛出异常时触发noexcept(true))?

请提供该标准的参考.关于使用noexcept构造函数的任何警告的提示也是受欢迎的.谢谢!

c++ constructor language-lawyer noexcept c++11

10
推荐指数
1
解决办法
624
查看次数

将删除的函数声明为noexcept是否有任何意义?

考虑这两个可能的类定义:

图表A:

struct A
{
    A() = delete;
};
Run Code Online (Sandbox Code Playgroud)

图表A':

struct A
{
    A() noexcept = delete;
}
Run Code Online (Sandbox Code Playgroud)

声明删除的函数是否有任何意义noexcept

c++ exception-specification deleted-functions noexcept

10
推荐指数
1
解决办法
275
查看次数

在调用C函数的其他非抛出内联函数中添加noexcept?

我已经为某些C库实现了C++绑定.库API调用可能会失败,但显然不能抛出任何东西; 为了这个问题的目的,我的绑定都是内联的.

现在,对于我的大多数内联函数/方法,编译器可以弄清楚不能抛出异常; 例如,假设我有:

bool foo() { 
    auto result = wrapped_lib_foo(); 
    return some_constexpr_nothrow_cond(result); 
}
Run Code Online (Sandbox Code Playgroud)

我应该用这样的功能/方法标记noexcept吗?

笔记:

c++ noexcept c++11

10
推荐指数
1
解决办法
394
查看次数

`nodcept`函数中的`std :: terminate`调用,可见性有限 - gcc vs clang codegen

请考虑以下代码段:

void f();

void a()          { f(); }
void b() noexcept { f(); }
Run Code Online (Sandbox Code Playgroud)

在上面的场景f中,当前转换单元中的编译器看不到正文.因此,由于b已标记noexcept,因此必须在调用方生成其他代码,以确保捕获并std::terminate调用异常.

这就是clang++ -Ofast -std=c++2a(主干版本):

a(): # @a()
  jmp f() # TAILCALL
b(): # @b()
  push rax
  call f()
  pop rax
  ret
  mov rdi, rax
  call __clang_call_terminate
__clang_call_terminate: # @__clang_call_terminate
  push rax
  call __cxa_begin_catch
  call std::terminate()
Run Code Online (Sandbox Code Playgroud)

但是,g++ -Ofast -std=c++2a(主干版):

a():
  jmp f()
b():
  jmp f()
Run Code Online (Sandbox Code Playgroud)

godbolt.org上的实例


怎么g++逃避这个?不应该在调用方生成代码,因为主体f不可见? …

c++ code-generation exception noexcept c++11

10
推荐指数
1
解决办法
197
查看次数

noexcept 对显式默认的移动构造函数/赋值运算符有影响吗?

class C
{
    public:
        C(C&&) = default; // (1)
        C& operator=(C&&) = default; // (1)

        C(C&&) noexcept = default; // (2)
        C& operator=(C&&) noexcept = default; // (2)
}
Run Code Online (Sandbox Code Playgroud)

据我所知,如果移动构造函数/赋值运算符是由用户隐式生成或显式默认的(1),编译器将noexcept根据类的所有成员是否noexcept为移动操作提供保证来决定是否应该使用这些特殊成员函数。但是,如果我想使用默认移动特殊成员并强制它们不noexcept考虑移动操作的底层成员异常保证,该怎么办?(1)和声明之间的编译器有什么区别吗(2)

c++ move-semantics noexcept

10
推荐指数
1
解决办法
541
查看次数

如果类包含标准容器,是否可以标记类move- operation noexcept?

使用标准容器成员对类实现移动操作的惯用方法不能noexcept,因此不能通过类似的操作移动vector.push_back().还是我弄错了?

为了加快速度

vector<Elem> data;
// ...
data.push_back( elem );
Run Code Online (Sandbox Code Playgroud)

我们鼓励我们进行移动操作noexcept- 因此在向量调整大小期间,库可以安全地将元素移动到重新分配的存储.

class Elem {
    // ...
    Elem(Elem&&) noexcept;            // noexcept important for move
    Elem& operator=(Elem&&) noexcept; // noexcept important for move
};
Run Code Online (Sandbox Code Playgroud)

到目前为止一切顺利,现在我的elems可以更快地被推回.

但是:如果我添加一个容器作为成员,我的班级仍可以标记为noexcept-move吗?所有标准容器都没有移动noexcept!

class Stuff {
    vector<int> bulk;
    // ...
    Stuff(Stuff&& o)  // !!! no noexcept because of vector-move  
      : bulk(move(o.bulk))
      {}
    Stuff& operator=(Stuff&&) // !!! no noexcept...
      { /* appropriate implementation */ }
};
Run Code Online (Sandbox Code Playgroud)

这也意味着,我们也可以不依赖编译器生成的移动操作,对吧?以下完整的类也没有noexcept …

c++ containers move-semantics noexcept c++11

9
推荐指数
1
解决办法
563
查看次数

我们可以在noexcept规范中引用成员变量吗?

请考虑以下代码段:

template<class Tuple>
class vector
{
public:
    typename Tuple::size_type size() const noexcept(noexcept(m_elements.size())) {
        return m_elements.size();
    }

private:
    Tuple m_elements;
};

class tuple
{
public:
    using size_type = std::size_t;

    size_type size() const { return 0; }
    size_type size() noexcept { return 0; }
};    

int main()
{
    vector<tuple> x;
    static_assert(noexcept(x.size()), "x.size() might throw");

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

m_elements在说明noexcept符中使用成员变量是合法的吗?GCC 5.2(C++ 17)产生的编译器错误 m_elements未在此范围内声明.而clang 3.6(C++ 17)编译时没有任何错误.

如果我改用,两个编译器都不会产生错误noexcept(std::declval<Tuple const&>().size()).但是,正如您所看到的,我创建了一个简单的示例类tuple,无论是否Tuple具有合格的重载都至关重要size.

从我的角度来看,它更直观, …

c++ language-lawyer noexcept c++14 c++17

9
推荐指数
1
解决办法
440
查看次数

为什么没有std :: uninitialized_move_if_noexcept?

C++ 17补充说std::uninitialized_move,但没有内部std::uninitialized_move_if_noexcept使用std::move_if_noexcept.在我看来,这将是有用的,因为现在,如果我们想要重新分配,我们仍然需要写一些东西

if constexpr (!std::is_nothrow_move_constructible_v<value_type>
              && std::is_copy_constructible_v<value_type>)
  std::uninitialized_copy(...);
else 
  std::uninitialized_move(...); 
Run Code Online (Sandbox Code Playgroud)

有没有特别的原因为什么std::uninitialized_move_if_noexcept没有在C++ 17中引入?

c++ move placement-new noexcept c++17

9
推荐指数
1
解决办法
236
查看次数