2016-06-22 1 views
0

La question est le code. On dirait que la 2ème fonction est plus spéciale que la 1ère. Pourquoi le plus général est appelé dans le code suivant? Comment puis-je faire l'autre fonction à utiliser?résolution de surcharge des modèles de fonction

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; 
} 

Notez que je passe l'objet Dérivé à la fonction.

+0

Ce message peut vous aider: http://stackoverflow.com/questions/22411482/c-template-functions-overload-resolution. Voir la réponse de @ NikosAthanasiou. – chema989

+1

Copie possible de: http://stackoverflow.com/questions/31563580/c-templated-function-overloading-rules?lq=1 – sameerkn

Répondre

0

Notez que je passe l'objet Dérivé à la fonction.

Dans ce cas, il doit y avoir une conversion implicite (Derived<T>-Base<T>) pour l'argument du modèle 2 de fonction. Alors que pour le 1er modèle de fonction c'est un match exact et préféré.

Comment puis-je utiliser l'autre fonction?

Vous pouvez modifier le type de paramètre du 2ème modèle de fonction pour éviter une conversion implicite. Vous pouvez également utiliser std::enable_if avec std::is_base_of pour le faire fonctionner uniquement avec la classe de base et ses classes dérivées.

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


BTW: Je pense que Base::print() devrait être une fonction virtuelle.

0

réponse simple serait:

  • template instantiation sont effectuées au moment de la compilation: Au moment de la compilation il n'y a pas de fonction qui peut prendre Derived<int> donc void func(T x) est utilisé pour instancier la définition de ce genre de fonction.

implicit dynamic conversion sont effectuées lors de l'exécution.