2016-05-16 12 views
4

コンパイラが私のProductionクラスのコピーコンストラクタを選択し、他の候補関数を持たない理由を理解できません。 私は、エラーを示すために、最小限の例を作っ:Variadicのテンプレートコンストラクタとコピーコンストラクタ

#include <string> 
#include <typeindex> 
#include <iostream> 

struct DummyProduction { 
}; 

struct Dep { 
}; 

struct Pro { 
}; 

class ModuleBase { 
}; 

template<typename Production = DummyProduction> 
class Provider { 
public: 
    template<typename... Dependencies> 
    Provider(ModuleBase& module, Dependencies... args) 
    { 
    std::cout << "Provider called!" << std::endl; 
    } 
    Provider(const Provider&) = delete; 
}; 

class TargetController : public ModuleBase, 
    public Provider<Pro>, 
    public Provider<> 
{ 
public: 
    TargetController(); 
private: 
    Dep p; 
}; 

TargetController::TargetController() : 
    ModuleBase(), 
    Provider<Pro>(*this, &p), 
    Provider<>(*this), 
    p() 
{ 
} 

int main() 
{ 
    TargetController x; 
    return 0; 
} 

私はgccと打ち鳴らすとそれを試してみました。ここに非現実的な例へのリンクがあります:link

Provider<Pro>(*this, p)の場合、右側のコンストラクタが呼び出されます。しかし、2番目の例のProvider<>(*this)の場合、コンパイラーはコピーコンストラクターを呼び出そうとします。

Overload resolutionページから私が理解したところでは、式に一致するすべての関数が候補関数セット内に入るはずです。しかし、バリデーションコンストラクタは、依存関係のないプロバイダのセットの中にはないか、またはコンパイラは、beeingが削除されたにもかかわらずコピーコンストラクタを選択します。

この現象を回避する方法はありますか?

+0

このような質問は私を謙虚にします:)。 +1 – Makketronix

+1

[OT]: 'p'は' Provider (* this、p) 'の呼び出しではまだ構築されていません。 – Jarod42

+0

@ Jarod42はい、そうです。コードを最小限に抑えながら、忘れました。 – Nagua

答えて

2

関数/メソッドがdeletedであるという事実は、それを過負荷リストから削除しません。 そして、コピーコンストラクタはテンプレートメソッドよりも高い優先度を持ちます(完全一致ではないため)。

としては、あなたが期待されるタイプにこれを唱えてもよい解決策:

TargetController::TargetController() : 
    ModuleBase(), 
    Provider<Pro>(*this, p), 
    Provider<>(static_cast<ModuleBase&>(*this)) 
{ 
} 

Demo

+0

また、オーバーロードリストからコピーコンストラクタを削除するオプションがないことも悪いことです。はい、これは私のコードで動作しています。だから、私は今それを使わなければならないと思う。ありがとうございました。 – Nagua

0

を鋳型コンストラクタがコンストラクタをコピーされることはありません。 baseのコンストラクタを呼び出してbase(または派生)への参照を渡すと、コピーコンストラクタが呼び出されるはずです。この文脈では、テンプレートはオプションではありません。

Provider<>(*this) 

このようなコンテキストです。

私はVSがまだ間違っていると信じていることに注目しています。そのコンパイラでは、&のベースにキャストするか、テンプレートを呼び出します。

+0

これがなぜ機能していないのか説明してくれてありがとう。使用できる他のコンストラクタがないというC++標準への参照がありますか? – Nagua

関連する問題