函数模板
<utility>

std::move_if_noexcept

template <class T>  typename conditional < is_nothrow_move_constructible<T>::value ||                         !is_copy_constructible<T>::value,                         T&&, const T& >::type move_if_noexcept(T& arg) noexcept;
如果无异常则移动
返回 arg右值引用,除非复制比移动能提供更好的 强异常保证

强保证 由操作保证在发生异常时使对象处于操作之前的状态。这可以通过操作副本(因此在操作期间原始对象保持不变)或仅使用不抛出异常的操作(在这种情况下,提供更高级别的保证:无异常保证)来实现。

一些操作可以通过移动或复制对象来实现,通常是为 右值 移动,为 左值 复制:当对象不再需要时(例如 右值),移动通常比复制更有效率。

该函数如果类型是 无异常可移动构造(即,其移动构造函数从不抛出),则将参数类型选择为 右值引用;否则,如果类型是 可复制构造,则选择为 左值引用。如果类型两者都不是,则函数返回一个 右值,该右值将为 仅移动 类型(即使它们可能抛出)选择。

该函数返回与 move(arg) 相同的值,但返回类型根据 T 的属性转换为 T&&const T&

参数

arg
一个对象。

返回值

如果 T无异常可移动构造T 不是 可复制构造,则指向 arg右值引用
否则为 左值引用
返回类型使用 conditional 在两种类型之间选择:T&&const T&

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// move_if_noexcept example
#include <utility>      // std::move_if_noexcept
#include <iostream>     // std::cout

// function with lvalue and rvalue reference overloads:
template <class T> void overloaded (T&  x) {std::cout << "[lvalue]\n";}
template <class T> void overloaded (T&& x) {std::cout << "[rvalue]\n";}

struct A {   // copyable + moveable (noexcept)
  A() noexcept {}
  A (const A&) noexcept {}
  A (A&&) noexcept {}
};

struct B {   // copyable + moveable (no noexcept)
  B() {}
  B (const B&) {}
  B (B&&) {}
};

struct C {   // moveable only (no noexcept)
  C() {}
  C (C&&) {}
};

int main () {
  std::cout << "A: "; overloaded (std::move_if_noexcept(A()));
  std::cout << "B: "; overloaded (std::move_if_noexcept(B()));
  std::cout << "C: "; overloaded (std::move_if_noexcept(C()));
  return 0;
}

输出
A: [rvalue]
B: [lvalue]
C: [rvalue]


数据竞争

调用此函数不会引入数据竞争。
尽管请注意,将返回值传递给实现 移动语义 的函数通常涉及修改对象的值或有效性。

异常

无异常保证:此函数从不抛出异常。

另见