2016-01-22 5 views
6

このテンプレートctorはctorを非表示にしますか?ユニバーサルリファレンスを持つテンプレートコンストラクタはconstrutorを移動しませんか?

class A { 
    public: 
     template<typename T> 
     A(T &&t); 

     // move would be as this: 
     /* 
      A(A &&a); 
     */ 
}; 

この状況で私はどのようにしてmove ctorを実装する必要がありますか?デフォルトの構文A (A &&)またはテンプレートの特殊化が必要ですか?

+1

テンプレートベースのctorは少なくとも移動すると考慮されていないようです:http://coliru.stacked-crooked.com/a/3c995d34b40fb4bcこれが標準のケースでは、move ctorをいつも通り。 – user2079303

答えて

3

その最初のパラメータがタイプX &であれば、標準(案)

[class.copy]

3によれば、クラスXのため非鋳型コンストラクタは移動コンストラクタであります&、constX& &、volatileX & &、またはconst volatile X & &であり、他のパラメータがないか、 ametersにはデフォルトの引数があります(8.3.6)。 [例:Y :: Y(Y & &)は、移動コンストラクタです。

非テンプレートコンストラクタだけがコンストラクタを移動できます。コピーコンストラクタにも同じです。したがって、暗黙の移動コンストラクタが生成されます。

通常の方法で移動コンストラクタを実装します。暗黙の非テンプレート移動コンストラクタは、オーバーロードの解決によって優先されるため、特殊化は機能しません。

ただし、引数タイプがconst T&に正確に一致しない場合は、テンプレートリファレンスがオーバーロード解決に勝ちます。 Praveenの例に見られるように、これは簡単に起こり得る。

+1

**コピーコンストラクタにも同じ**が適用されます。 'A a2 {a1};'は 'コピーコンストラクタ 'の代わりに' template'を呼び出します。どうして? 'a1'は' const'ではないので、http://ideone.com/JAfjLy – Praveen

+3

@Praveen。転送参照は本当に貪欲です。 – TartanLlama

5

回答が間違っています。 template <typename T> A(T &&t) { }は移動コンストラクタではありませんが、それはすでに分かっています。コンパイラは、暗黙のうちに、この場合には移動コンストラクタを宣言し、期待通り、通常のオーバーロードの解決は動作します:

A a{2}; // calls template 
A b = std::move(a); // calls move 
A c{a}; // calls template 

テンプレートコンストラクタが「移動」でなくても、cに移動されることからaを排除何もありませんコンストラクタ。

+3

テンプレートが移動コンストラクタとしてカウントされないことは、Askerが知っていることをどのように知っていますか?受け入れられた答えでは、移動コンストラクタは暗黙のうちに宣言されていないと、どこで言いますか? (または、「受け入れられた回答が間違っています」_を参照してください) – nwp

関連する問題