ムーブ代入演算子
クラス T
のムーブ代入演算子は、 T&&、 const T&&、 volatile T&& または const volatile T&& 型の引数をちょうど1個取る operator= という名前の非テンプレート非静的メンバ関数です。
目次 |
[編集] 構文
class_name & class_name :: operator= ( class_name && )
|
(1) | (C++11以上) | |||||||
class_name & class_name :: operator= ( class_name && ) = default;
|
(2) | (C++11以上) | |||||||
class_name & class_name :: operator= ( class_name && ) = delete;
|
(3) | (C++11以上) | |||||||
[編集] 説明
- ムーブ代入演算子の一般的な宣言。
- ムーブ代入演算子をコンパイラに強制的に生成させます。
- 暗黙のムーブ代入を回避します。
ムーブ代入演算子は、オブジェクトが代入式の左側に現れ、その右側が同じ型または暗黙に変換可能な型の右辺値であるときなどに、オーバーロード解決によって選択されたときに、呼ばれます。
ムーブ代入演算子は、一般的には、引数が保持しているリソース (動的に確保されたオブジェクトへのポインタ、ファイルディスクリプタ、 TCP ソケット、入出力ストリーム、実行中のスレッド、など) をコピーするのではなく「盗み」、その引数を何らかの有効だけれどもそれ以外の点では不定な状態に置きます。 例えば、 std::string や std::vector のムーブ代入は引数を空にするかもしれません。 しかしこれは保証ではありません。 ムーブ代入は普通の代入より制限が少なく (多くではなく) 定義されます。 普通の代入は完全なデータのコピーを2つ残さなければなりませんが、ムーブ代入は1つ残すことが要求されるだけです。
[編集] 暗黙に宣言されたムーブ代入演算子
クラス型 (struct、 class または union) に対してユーザ定義されたムーブ代入演算子が提供されず、以下のすべてが真の場合、
- ユーザ宣言されたコピーコンストラクタがない。
- ユーザ宣言されたムーブコンストラクタがない。
- ユーザ宣言されたコピー代入演算子がない。
- ユーザ宣言されたデストラクタがない。
|
(C++14未満) |
コンパイラはそのクラスの inline public
メンバとしてシグネチャ T& T::operator=(T&&)
を持つムーブ代入演算子を宣言します。
クラスは複数のムーブ代入演算子、例えば T& T::operator=(const T&&) と T& T::operator=(T&&) の両方を持つことができます。 何らかのユーザ定義されたムーブ代入演算子が存在する場合でも、ユーザはキーワード default
を用いて暗黙に宣言されたムーブ代入演算子の生成を強制できます。
暗黙に宣言された (またはその最初の宣言においてデフォルト化された) ムーブ代入演算子は、動的例外指定 (C++17未満)例外指定 (C++17以上)で説明されている通りの例外指定を持ちます。
いかなるクラスに対しても何らかの代入演算子 (ムーブまたはコピー) が必ず宣言されるため、基底クラスの代入演算子は必ず隠蔽されます。 基底クラスの代入演算子を取り込むために using 宣言が使用され、その引数の型が派生クラスの暗黙の代入演算子の引数の型と同じである場合は、その using 宣言も暗黙の宣言によって隠蔽されます。
[編集] 削除された暗黙に宣言されたムーブ代入演算子
クラス T
に対する暗黙に宣言されたまたはデフォルト化されたムーブ代入演算子は、以下のいずれかが真の場合、削除されたものとして定義されます。
-
T
が const である非静的データメンバを持つ。 -
T
が参照型の非静的データメンバを持つ。 -
T
がムーブ代入できない (削除されている、アクセス不可能な、または曖昧なムーブ代入演算子を持つ) 非静的データメンバを持つ。 -
T
がムーブ代入できない (削除されている、アクセス不可能な、または曖昧なムーブ代入演算子を持つ) 直接または仮想の基底クラスを持つ。
|
(C++14未満) |
削除された暗黙に宣言されたムーブ代入演算子はオーバーロード解決では無視されます。 |
(C++14以上) |
[編集] トリビアルなムーブ代入演算子
以下のすべてが真の場合、クラス T
に対するムーブ代入演算子はトリビアルです。
- ユーザ提供されていない (つまり、暗黙に定義されている、またはデフォルト化されている)。
-
T
が仮想メンバ関数を持たない。 -
T
が仮想基底クラスを持たない。 -
T
のすべての直接の基底について、選択されたムーブ代入演算子がトリビアルである。 -
T
のすべてのクラス型 (またはクラスの配列型) の非静的メンバについて、選択されたムーブ代入演算子がトリビアルである。
|
(C++14以上) |
トリビアルなムーブ代入演算子はトリビアルなコピー代入演算子と同じ動作、つまり、 std::memmove によって行われたかのようにオブジェクト表現のコピーを行います。 C 言語と互換性のあるすべてのデータ型 (POD 型) はトリビアルにムーブ代入可能です。