Humam Helfawiは、ポイントを得ました。
私は彼の答えを完了しようとします。
Svalorzen:出力は "コピーコンストラクタ" である
#include <iostream>
template <typename T>
struct X {
X() : x(5) {}
template <template <typename> class S>
X (const S<T> & y) : x(y.x)
{ std::cout << "templated constructor" << std::endl; }
X (const X<T> & y) : x(y.x)
{ std::cout << "copy constructor" << std::endl; }
T x;
};
int main()
{
X<int> y;
auto x = y;
return 0;
}
このコードを見て。
コンパイラが一致するテンプレート関数と一致するプレーン(テンプレートなし)関数を見つけたら、より具体的なプレーンを選択します。
今すぐコピーコンストラクタ
#include <iostream>
template <typename T>
struct X {
X() : x(5) {}
template <template <typename> class S>
X (const S<T> & y) : x(y.x)
{ std::cout << "templated constructor" << std::endl; }
T x;
};
int main()
{
X<int> y;
auto x = y;
return 0;
}
の定義を削除して、移動のコンストラクタなしとCOUT(「テンプレートコンストラクタ」)とあなたの例を取得しました。
出力が空であることがわかります。
これは、コンパイラがデフォルトバージョンの暗黙的に存在するコピーコンストラクタを選択するためです。
移動コンストラクタを追加すると、コピーコンストラクタが削除されたことがあります。しかし、コピーコンストラクタは常に存在しています(削除されたとしてマークされています)、コンパイラはそれを考慮します。したがって、コンパイラが "x = y"を実装しようとすると、テンプレートコンストラクタに一致し、コピーコンストラクタと一致し、コピーコンストラクタを選択します(より具体的に)。
あなたは
X (const X<T> &) = default;
を追加するときは、コピーコンストラクタを使用するようにコンパイラを許可します。
p.s .:申し訳ありませんが、私の悪い英語です。
コードでエラーを投稿することを検討してください。 – zneak