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 (das const 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 bei

    MyClass<int> a(42);
    -(-a);
    cout << a.x;
    

    sehr unerwartet!


Log in to reply