2016-06-22 9 views
0

Frage ist der Code. Es sieht so aus, als ob die 2. Funktion spezieller ist als die 1. Funktion. Warum wird der allgemeinere im folgenden Code aufgerufen? Wie kann ich die andere Funktion verwenden?Überladung Auflösung von Funktionsvorlagen

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

Beachten Sie, dass ich das Derived-Objekt an die Funktion übergebe.

+0

Dieser Beitrag kann Ihnen helfen: http://stackoverflow.com/questions/22411482/c-template-functions-overload-resolution. Siehe die Antwort von @NikosAthanasiou. – chema989

+1

Mögliches Duplikat von: http://stackoverflow.com/questions/31563580/c-templated-function-overloading-rules?lq=1 – sameerkn

Antwort

0

Beachten Sie, dass ich das Derived-Objekt an die Funktion übergebe.

In diesem Fall muss es eine implizite Konvertierung (Derived<T>-Base<T>) für das Argument der zweiten Funktion Vorlage. Während für die 1. Funktionsvorlage ist es eine exakte Übereinstimmung und bevorzugt.

Wie kann ich die andere Funktion verwenden?

Sie können den Parametertyp der 2. Funktionsvorlage ändern, um eine implizite Konvertierung zu vermeiden. Sie können auch std::enable_if mit std::is_base_of verwenden, damit es nur mit der Basisklasse und ihren abgeleiteten Klassen funktioniert.

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: Ich denke, Base::print() eine virtuelle Funktion sein sollte.

0

Einfache Antwort wäre:

  • template instantiation werden bei der Kompilierung durchgeführt: Beim Kompilieren gibt es keine Funktion, die Derived<int> nehmen kann daher void func(T x) verwendet wird, um die Definition dieser Art von instanziiert Funktion.

implicit dynamic conversion sind zur Laufzeit fertig.

Verwandte Themen