Wenn Sie eine Memberfunktion einer Klassenvorlage außerhalb der Klasse definieren, definieren Sie nur die Funktion für die entsprechende Funktion, die in der Klassenvorlage deklariert wurde. Sie erstellen keine neue Funktionsvorlage, die anderen Parametern entsprechen könnte. In Ihrem Beispiel:
template <class T, class U = T>
class A {
public:
void f(); // This is the declaration of A<T,U>::f()
};
template <class T>
class A<T, T> {
public:
void f(); // This is the declaration of A<T,T>::f()
};
template <class T, class U>
void A<T, U>::f() {} // This is the definition of A<T,U>::f()
// There is no definition of A<T,T>::f()
glaube ich, was Sie denken ist, dass der Compiler werden sehen, dass Sie A<int,int>::f()
fordern und die Mitgliedsfunktionsdefinitionen durchsehen und finden, das passt, aber das ist nicht, was passiert. Der Compiler durchsucht immer die Klassenvorlagen, um zu ermitteln, welche Funktion aufgerufen werden soll. Sobald er eine Übereinstimmung gefunden hat, sucht er nach der entsprechenden Definition. In Ihrem Fall rufen Sie A<int,int>::f()
, so dass es zuerst nach einer Klassendefinition sucht, die A<int,int>
entspricht, und es findet Ihre A<T,T>
Klassenvorlagenspezialisierung. Es sieht, dass A<T,T>
tatsächlich eine Elementfunktion namens f
hat, die Ihrem Funktionsaufruf entspricht, was bedeutet, dass A<T,T>::f()
instanziiert werden muss. Um A<T,T>::f()
zu instanziieren, sucht der Compiler nach der Definition A<T,T>::f()
, jedoch findet es es nicht. Es findet nur die Definition A<T,U>::f
, die keine Übereinstimmung ist. Der passende Template-Parameter, der verwendet wird, um eine korrekte Funktionsdeklaration zu finden, trifft nicht zu.
Whare sind die Unterschiede zwischen A und A ? Möglicherweise können Sie eine Spezialisierung der Klasse vermeiden (mit enable_if, SFINAE ...). –
ysdx
@ysdx Der Unterschied liegt in der Deklaration einer lokalen Klasse und deren Verwendung in einigen Methoden. –