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

履歴 編集

concept
<concepts>

# std::move_constructible(C++20)

    namespace std {
      template<class T>
      concept move_constructible = constructible_from<T, T> && convertible_to<T, T>;
    }

## 概要

`move_constructible`は、任意の型`T`がムーブ構築可能であること表すコンセプトである。

## モデル

`T`がオブジェクト型ならば`rv`を`T`の右辺値、`u2`を`rv`と等値な`T`のオブジェクトとすると、この`rv, u2`について以下の条件を満たす場合に限って型`T`は`move_constructible`のモデルである。

- `T u = rv;`の定義の後では`u`と`u2`は等値であること
- `T(rv)`は`u2`と等値であること
- `T`が`const`ではないのであれば、上記の2つの条件内の式の後の`rv`は有効だが未規定な状態となる。そうでなければ`rv`は変更されない。
  - 標準ライブラリの型のオブジェクトはムーブされた後では有効だが未規定な状態となる。

## 例

    #include <iostream>
    #include <concepts>

    template<std::move_constructible T>
    void f(const char* name) {
      std::cout << name << " is move constructible" << std::endl;
    }

    template<typename T>
    void f(const char* name) {
      std::cout << name << " is not move constructible" << std::endl;
    }

    struct S {
      S(S&&) = delete;

      S(int m) : n(m) {}

      int n = 0;
    };

    struct M {
      M(M&&) = default;
    };

    int main() {
      f<int>("int");
      f<S>("S");
      f<M>("M");
    }

### 出力

    int is move constructible
    S is not move constructible
    M is move constructible

## バージョン

### 言語

- C++20

### 処理系

- Clang: ??
- GCC: 10.1 ✅
- Visual C++: 2019 Update 3 ✅

## 関連項目

- C++20 コンセプト
- `is_move_constructible`

## 参照

- P0898R3 Standard Library Concepts
- P1754R1 Rename concepts to standard_case for C++20, while we still can