【问题标题】:disabled exceptions and noexcept()禁用异常和 noexcept()
【发布时间】:2015-07-28 09:48:49
【问题描述】:

std::swap 是这样声明的:

template <class T> void swap (T& a, T& b)
    noexcept (is_nothrow_move_constructible<T>::value && 
              is_nothrow_move_assignable<T>::value);

如果我在我的程序中禁用异常(例如 -fno-exceptions 用于 g++)如果我的自定义类型启用了移动,std::swap 将使用移动操作,无论它们是 noexcept 还是不是吗?

编辑:后续问题:

在意识到 std::swap 将始终使用移动(如果我的类型有它们)之后,我真正的问题是像 is_nothrow_move_assignable&lt;&gt; 这样的特征会发生什么?

如果我的类型有 noexcept(true) 移动操作,std::vector 在重新分配时是否总是使用移动?

【问题讨论】:

  • 编译器的move 规则与异常正交。
  • @AmiTavory 移动规则是的,但是像 is_nothrow_move_constructible 这样的特征呢?
  • 编写一个简短的(3 行)测试程序,打印出is_nothrow_move_constructible 的结果,使用和不使用-fno-exceptions 进行编译
  • @RichardCritten 我刚刚尝试过 - 使用 -fno-exceptions 并不能满足所有需求 noexcept(true)...

标签: c++ c++11 g++ noexcept


【解决方案1】:

swap 上的 noexcept 规范仅告诉 用户 她可以在哪里使用 swap 而不会遇到异常。 实现实际上总是等价于

auto tmp = std::move(a);
a = std::move(b);
b = std::move(tmp);

当且仅当重载决策选择移动赋值运算符和/或构造函数时,它会移动对象。

【讨论】:

    【解决方案2】:

    是的。 noexcept 只是指定std::swap 不会抛出,如果T 的移动构造函数和移动赋值不会抛出。它不会影响swap 主体的行为——无论它们是否抛出,也不管您是否在启用异常的情况下编译,它将使用T 的移动构造函数和移动赋值。

    【讨论】:

      猜你喜欢
      • 2014-03-03
      • 2016-06-11
      • 2023-04-01
      • 1970-01-01
      • 1970-01-01
      • 2022-08-03
      • 1970-01-01
      • 1970-01-01
      • 2015-05-04
      相关资源
      最近更新 更多