2016-06-22 15 views
0

質問はコードです。 2番目の関数が1番目の関数よりも特別なように見えます。次のコードでより一般的なものが呼び出されるのはなぜですか?他の機能を使用するにはどうすればいいですか?関数テンプレートのオーバーロード解決

template <typename T> 
class Base{ 
public: 
    Base(){} 
    void print() const {cout<<"Base class"<<endl;} 
}; 

template <typename T> 
class Derived :public Base<T>{ 
public: 
    Derived() {} 
    void print() const {cout<<"Derived class"<<endl;} 
}; 

template <typename T> 
void func(T x){ // <----- Why is function is called? 
    x.print(); 
    cout<<"in func(T)"<<endl; 
} 

template <typename T> 
void func(const Base<T>& x){ 
    x.print(); 
    cout<<"in func(Base<T>)"<<endl; 
} 

int main() { 
    Base<int> b; 
    Derived<int> d; 
    func(d); 
    return 0; 
} 

私は、Derivedオブジェクトを関数に渡していることに注意してください。

+0

この投稿はあなたを助けることができます:http://stackoverflow.com/questions/22411482/c-template-functions-overload-resolution @NikosAthanasiouの答えを見てください。 – chema989

+1

可能な複製:http://stackoverflow.com/questions/31563580/c-templated-function-overloading-rules?lq=1 – sameerkn

答えて

0

派生オブジェクトを関数に渡していることに注意してください。

この場合、2番目の関数テンプレートの引数に1つの暗黙の変換(Derived<T>からBase<T>まで)が必要です。 1番目の関数テンプレートでは、完全に一致し、優先されます。

他の機能を使用するにはどうすればよいですか?

暗黙の変換を避けるために、2番目の関数テンプレートのパラメータタイプを変更できます。また、std::enable_ifstd::is_base_ofを使用すると、基本クラスとその派生クラスでのみ動作するようにすることもできます。

template <typename T, template <typename> class D> 
typename std::enable_if<std::is_base_of<Base<T>, D<T>>::value>::type 
func(const D<T>& x){ 
    x.print(); 
    cout<<"in func(Base<T>)"<<endl; 
} 

Live Demo


ところで:私はBase::print()は仮想関数であるべきだと思います。

0

簡単な答えは次のようになります。

  • template instantiationは、コンパイル時で行われています。コンパイル時にDerived<int>を取ることができます何 機能はありませんのでvoid func(T x)は、その種類の定義をインスタンス化するために使用されます関数。

implicit dynamic conversion実行時に実行されます。

関連する問題