ich zur Zeit typisieren bin Lesen „Effective C++“ und gibt es ein Kapitel, das Code similiar dazu enthält:C++ Hinzufügen von Freund zu einer Template-Klasse, um
template <typename T>
class Num {
public:
Num(int n) { ... }
};
template <typename T>
Num<T> operator*(const Num<T>& lhs, const Num<T>& rhs) { ... }
Num<int> n = 5 * Num<int>(10);
Das Buch sagt, dass dies nicht funktioniert (und in der Tat nicht), weil Sie nicht erwarten können, dass der Compiler implizite Typumwandlung verwendet, um eine Vorlage zu spezialisieren.
Als Lösung wird empfohlen, die "friend" -Syntax zu verwenden, um die Funktion innerhalb der Klasse zu definieren.
//It works
template <typename T>
class Num {
public:
Num(int n) { ... }
friend
Num operator*(const Num& lhs, const Num& rhs) { ... }
};
Num<int> n = 5 * Num<int>(10);
Und das Buch schlägt vor, dieses Freund-Erklärung, was zu verwenden, wenn ich implizite Konvertierung in einen Template-Klasse Typen benötigen. Und alles scheint einen Sinn zu ergeben.
Aber warum kann ich nicht das gleiche Beispiel mit einer gemeinsamen Funktion arbeiten, nicht ein Operator?
template <typename T>
class Num {
public:
Num(int n) { ... }
friend
void doFoo(const Num& lhs) { ... }
};
doFoo(5);
Diesmal der Compiler Beschwerden, dass er überhaupt keine "DoFoo" finden kann. Und wenn ich die DoFoo außerhalb der Klasse deklariere, bekomme ich die vernünftige nicht übereinstimmende Typen Fehler. Scheint so, als ob der "Freund ..." Teil einfach ignoriert wird.
Also gibt es ein Problem mit meinem Verständnis? Was ist der Unterschied zwischen einer Funktion und einem Operator in diesem Fall?
Beachten Sie, wie mindestens ein Argument von 'Operator *' muss eine 'Num' sein. Dies ist bei 'doFoo' nicht der Fall. Ihr Typ könnte von "int" konstruierbar sein, ohne dass "T" selbst "int" ist. Der Spaß ist, dass es immer noch nicht funktionieren würde, wenn Ihre konvertierenden Konstruktoren eine Entsprechung zu den Template-Argumenten der Klassenvorlage hätten. Sie können ein Klassenvorlagenargument nicht über eine Elementfunktion dieser Vorlage ableiten. Sie können das umgehen, indem Sie eine 'make_num'-Funktion bereitstellen. –
pmr