2016-08-18 8 views
7

テンプレート化されたコンストラクタは、削除されたコピーコンストラクタのために立つことができますか?

template<typename T> 
struct Foo 
{ 
    Foo(const Foo&) = delete; 
    template <typename Y> 
    Foo(const Foo<Y>&){} 
}; 

を考えてみましょテンプレートコンストラクタの適切なインスタンス化は、コピーコンストラクタのためで立っていますか?私はそれが(コピーコンストラクタはテンプレート関数であってはならないので)普通ではないことを知っていますが、ここで私はコピーコンストラクタを削除しました。

+4

'Fooの(のconst T&)は'コピーコンストラクタではありません。 'Fooの(定数を持っているが存在しませんFoo&) 'になります。 – aschepler

+0

申し訳ありませんが、私はテンプレート構文があったと思います間違っている。今はいいですか? –

+1

削除された関数は、依然として過負荷解決のために存在します。それを使用しようとするのは単なる誤りです。一方、同じタイプからコピーを作成するのは本当に珍しいことです。 –

答えて

3

いいえ、それはできません:オーバーロードの解決は、常に最初の非テンプレート関数を考慮し、delete Dの1に遭遇した場合、オーバーロードの解決ではなく、検討されているテンプレートのオーバーロードを失敗します。

その後

  1. Foo<int> bar(double_foo);に注意して二つの変数

    Foo<double> double_foo; 
    Foo<int> int_foo; 
    

    を考え、私はその後、ラインであなたのクラスに

    Foo() = default;

    をデフォルトコンストラクタを導入することを許可が原因許可されていますテンプレート

  2. Foo<int> bar(int_foo);はあなたがFoo(const Foo&&) = default;を書き込むことによって移動コンストラクタを再導入した場合delete Dコンストラクタ
  3. Foo<int> bar = Foo<int>();許されるため許可されていません。 Foo<int> bar(Foo<int>());は前方宣言であるため、=構文を使用する必要があります。

最後に、あなたのアサーションである "コピーコンストラクタはテンプレート関数であってはいけません"は正しくありません。 @LightnessRacesInOrbitのクレジット:

C++ 14 12.8.2「その最初のパラメータはタイプX &、constのX &である場合、クラスXのための非テンプレートコンストラクタは、X &揮発性 コピー コンストラクタですまたはconstの揮発性X &、およびいずれかの他のパラメータまたは他の 他のすべてのパラメータがデフォルト引数(8.3.6)。

+0

非常に多くの感謝がありますが、あなたはあなたの最終的な注意を説明することができると思いますか? –

+1

Google「Most Vexing Parse」 – Bathsheba

4

ここでの問題は、削除された機能が依然として過負荷解決に関与していることです。だから、

Foo<int> a; 
Foo<int> b{a}; 

与えられた実行可能な機能が削除されたコピーコンストラクタと推定されるテンプレート引数intを持つテンプレートコンストラクタです。非テンプレートなので、削除されたコピーコンストラクタが勝ちます。削除された関数を使用すると、プログラムが不正になります。

だから、テンプレートコンストラクタは、同じ型のオブジェクトをコピーするためのコピーコンストラクタとしてインスタンス化することはできません。

関連する問題