Template + Überladen von Operator + inline (Fehler)
-
Hallo,
ich habe eine Klasse mit Spezialisierung erstellt welche nur definierte Typen zulässt.
Nun wollte ich aber die überladene Operatoren außerhalb der Klasse als inline definieren, aber ich bekomme Compiler Fehler.Hier ist ein Beispiel
#include <iostream> using namespace std; template<typename T, typename Type = std::enable_if<std::is_arithmetic<T>::value, T>::type> class MyClass final{ public: MyClass(T x) { this->x = x; } const MyClass operator-() { this->x *= -1; return *this; }; T x; }; int main() { MyClass<int> a(1); cout << "x: " << a.x << endl; -a; cout << "x: " << a.x << endl; system("pause"); return 0; }
Dieses Beispiel funktioniert, allerdings wenn ich den operator- außerhalb der Klasse definiere bekomme ich Compiler Fehler.
// Außerhalb der Klasse
#include <iostream> using namespace std; template<typename T, typename Type = std::enable_if<std::is_arithmetic<T>::value, T>::type> class MyClass final { // Line 12 public: MyClass(T x) { this->x = x; } const MyClass operator-(); T x; }; template<typename T, typename Type> inline const MyClass MyClass<T, Type>::operator-() { // Line 22 this->x *= -1; return *this; } int main() { MyClass<int> a(1); cout << "x: " << a.x << endl; -a; cout << "x: " << a.x << endl; system("pause"); return 0; }.
\main.cpp(22): error C2955: 'MyClass': use of class template requires template argument list
\main.cpp(12): note: see declaration of 'MyClass'
\main.cpp(22): error C2244: 'MyClass<T,Type>::operator -': unable to match function definition to an existing declaration
\main.cpp(22): note: see declaration of 'MyClass<T,Type>::operator -'
\main.cpp(22): note: definition
\main.cpp(22): note: 'const MyClass MyClass<T,Type>::operator -(void)'
\main.cpp(22): note: existing declarations
\main.cpp(22): note: 'const MyClass<T,Type> MyClass<T,Type>::operator -(void)'
-
Der Rückgabetyp passt nicht, die erste Fehlermeldung sagts schon aus.
-
Innerhalb einer Klasse kannst du die Template-Parameter weglassen und gehört sich sogar so, das wird dann immer auf den instanziierten Typ appliziert.
Außerhalb einer Klasse geht das dann nicht mehr so, so musst du aus dem Rückgabetype
const MyClass
ein,const MyClass<T, Type>
machen.
-
Der Rückgabetyp sollte aber besser
MyClass &
sein (dasconst
ohne Referenzrückgabe ist sowieso überflüssig), da der Operator ja das Klassenobjekt modifiziert (und damit dann sog. Operator-Chaining möglich wird - insbesondere wenn man denn noch andere Operatoren und/oder Funktionen implementiert).
Sonst wäre die Ausgabe beiMyClass<int> a(42); -(-a); cout << a.x;
sehr unerwartet!