Namespaces
Variants

C++ named requirements: MoveConstructible (since C++11)

From cppreference.net
C++ named requirements

その型のインスタンスが rvalue 引数から構築可能であることを指定します。

目次

要件

T は、以下の条件を満たす場合 MoveConstructible を満たします

与えられた

  • rv , 型 T rvalue 式,
  • u , 任意の識別子.

以下の式は有効であり、指定された効果を持たなければなりません。

事後条件
T u = rv ; u の値は初期化前の rv の値と等価である。

rv の新しい値は未規定である。

T ( rv ) T(rv) の値は初期化前の rv の値と等価である。

rv の新しい値は未規定である。

注記

クラスはこの型要件を満たすために move constructor を実装する必要はありません: const T& 引数を取る copy constructor は右辺値式にバインドできます。

MoveConstructible なクラスがムーブコンストラクタを実装する場合、 move semantics も実装することで、構築後の rv の値が未規定であるという事実を活用できる。

拡張コンテンツ

MoveConstructible クラスであることは std::is_move_constructible を意味しますが、逆は成り立ちません。なぜなら std::is_move_constructible は正しい引数でコンストラクタを呼び出す能力のみをチェックし、事後条件の値はチェックしないからです。

#include <iostream>
struct S
{
    int n;
    S(int in) : n{in} {}
    S(S&& other) { n = other.n + 1; }
};
static_assert(std::is_move_constructible_v<S>);
int main()
{
    S v{1};
    std::cout << "v.n = " << v.n << '\n';
    S u = std::move(v);
    // Class `S` doesn't satisfy a MoveConstructible requirement
    // The value of `u` is NOT equivalent to the value of `v` before the `u` initialization
    std::cout << "u.n = " << u.n << '\n';
}

出力:

v.n = 1
u.n = 2

参考文献

拡張コンテンツ
  • C++23 standard (ISO/IEC 14882:2024):
  • 16.4.4.2 Template argument requirements [utility.arg.requirements]

関連項目

型が右辺値参照から構築可能かどうかをチェックする
(クラステンプレート)
型のオブジェクトがムーブ構築可能であることを指定する
(コンセプト)