2016-07-16 8 views
3

のコメントを外すことにより、コンパイルされません:C++は、私は次のコードを持って移動オペレータ

template <typename T> 
struct X { 
    X() : x(5) {} 

    template <template <typename> class S> 
    X(const S<T> & y) : x(y.x) {} 

    // Uncomment and it does not compile anymore 
    // X(X&& z) : x(z.x) {} 

    T x; 
}; 

int main() 
{ 
    X<int> y; 
    auto x = y; 
    return 0; 
} 

を指定されたコードがコメント解除されたら、それはコンパイルされませんなぜあなたは説明してもらえますか?

+1

コードでエラーを投稿することを検討してください。 – zneak

答えて

2

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 .:申し訳ありませんが、私の悪い英語です。

3

コピーコンストラクタは、ムーブコンストラクタを宣言したため、暗黙的に削除として宣言されています。

デフォルト(またはユーザー定義された)を追加し、コンストラクタをコピーし、それが正常にコンパイルします:

X(const X<T>&)=default; 
+0

Mmhh ..私が宣言したテンプレートのcostructorは、コピーコンストラクタとしてカウントされないと思いますか?それとも間違っていますか? – Svalorzen

+1

@Svalorzenそうです、テンプレートコンストラクタは決してコピーコンストラクタではありません。 –

+0

正直言って、私はそれが何であるか理解していませんでした。しかし、それはコピーコンストラクタのようではありません。それは必要ではないテンプレートタイプを取る 'X' –

関連する問題