yohhoyの日記

技術的メモをしていきたい日記

どれがコピー/ムーブコンストラクタ?

C++11言語仕様において、どのようなコンストラクタが “コピーコンストラクタ”/“ムーブコンストラクタ” とみなされるのかについてメモ。

コピーコンストラク
第1引数にX&, const X&, volatile X&, const volatile X&のいずれかをとる非テンプレートなコンストラクタ。第2引数以降が存在する場合はそれらにデフォルト引数指定がなされていること。一般的にはX::X(const X&&)とする*1
ムーブコンストラク
第1引数にX&&, const X&&, volatile X&&, const volatile X&&のいずれかをとる非テンプレートなコンストラクタ。第2引数以降が存在する場合はそれらにデフォルト引数指定がなされていること。一般的にはX::X(X&&)とする*2

N3337 12.8/p2-4より引用。

2 A non-template constructor for class X is a copy constructor if its first parameter is of type X&, const X&, volatile X& or const volatile X&, and either there are no other parameters or else all other parameters have default arguments (8.3.6). [Example: X::X(const X&) and X::X(X&,int=1) are copy constructors.

struct X {
  X(int);
  X(const X&, int = 1);
};
X a(1);     // calls X(int);
X b(a, 0);  // calls X(const X&, int);
X c = b;    // calls X(const X&, int);

-- end example]
3 A non-template constructor for class X is a move constructor if its first parameter is of type X&&, const X&&, volatile X&&, or const volatile X&&, and either there are no other parameters or else all other parameters have default arguments (8.3.6). [Example: Y::Y(Y&&) is a move constructor.

struct Y {
  Y(const Y&);
  Y(Y&&);
};
extern Y f(int);
Y d(f(1)); // calls Y(Y&&)
Y e = d;   // calls Y(const Y&)

-- end example]
4 [Note: All forms of copy/move constructor may be declared for a class. [Example:

struct X {
  X(const X&);
  X(X&); // OK
  X(X&&);
  X(const X&&); // OK, but possibly not sensible
};

-- end example] -- end note]

関連URL

*1:暗黙に宣言されるコピーコンストラクタのプロトタイプから引用。条件によっては X::X(X&) が暗黙に定義されるが、この形の場合はconst Xからのコピーが出来ないことに注意。(12.8/p8)

*2:暗黙に宣言されるムーブコンストラクタのプロトタイプから引用。(12.8/p10)