最終更新日時: 2025年07月12日 02時16分44秒 (JST)
Koichi Murase が更新

履歴 編集

function template
<utility>

# std::move_if_noexcept(C++11)

    namespace std {
      template <class T>
      typename conditional<
        !is_nothrow_move_constructible<T>::value && is_copy_constructible<T>::value,
        const T&, T&&
      >::type move_if_noexcept(T& x) noexcept; // C++11

      template <class T>
      constexpr typename conditional<
        !is_nothrow_move_constructible<T>::value && is_copy_constructible<T>::value,
        const T&, T&&
      >::type move_if_noexcept(T& x) noexcept; // C++14
    }

## 概要

例外を投げないオブジェクトをムーブする。

この関数は、対象のオブジェクトが例外を投げないムーブコンストラクタを持っている場合に右辺値参照を返し、そうでなければconst左辺値参照を返す。

この関数は、複数のオブジェクトをムーブする際に、例外安全の強い保証を得ることを目的として使用される。

## 戻り値

`std::move(x)`

## 例外

投げない

## 例

    #include <iostream>
    #include <utility>

    struct A {
      A() {}

      A(const A&)
        { std::cout << "copy" << std::endl; }

      A(A&&) noexcept
        { std::cout << "move" << std::endl; }
    };

    struct B {
      B() {}

      B(const B&)
        { std::cout << "copy" << std::endl; }

      B(B&&)
        { std::cout << "move" << std::endl; }
    };

    int main()
    {
      // ムーブコンストラクタが例外を投げないのでムーブされる
      A a;
      A a1 = std::move_if_noexcept(a);

      // ムーブコンストラクタが例外を投げる可能性があるのでコピーされる
      B b;
      B b1 = std::move_if_noexcept(b);
    }

### 出力

    move
    copy

## バージョン

### 言語

- C++11

### 処理系

- Clang: ??
- GCC: 4.7.0 ✅
- ICC: ??
- Visual C++: 2012 ✅, 2013 ✅, 2015 ✅
  - 2012は正しく実装されていないと思われる。上記「例」のコードにおいて、ともにmoveしてしまう結果となる。

## 関連項目

- `is_nothrow_copy_constructible`
- `is_nothrow_move_constructible`

## 参照

- C++11 右辺値参照・ムーブセマンティクス
- N2983 Allowing Move Constructors to Throw
- N3471 Constexpr Library Additions: utilities, v3