Ich versuche, eine Num-Klasse mit Vorlagen zu erstellen. Diese Klasse muss ein öffentliches Attribut val
mit dem Typ type haben T
, der der einzige Vorlagenparameter ist. Wenn man einen Wert angibt, val
sollte das Attribut ( ) mit diesem Wert initialisiert werden. Dazu habe ich folgenden Code erstellt:
#include <iostream>
template<class T>
class Num {
public:
T val;
Num():val(0) { std::cout<<"default constr used"<<std::endl; }
Num(T value):val(value) {std::cout<<"constr (T value) used"<<std::endl; }
~Num() { std::cout<<"destructor used"<<std::endl; }
template<typename U>
Num operator+(const Num<U>& other) {
return val+other.value;
}
};
Außerdem habe ich die main()
Funktion zum Testen des Programms erstellt, die folgendermaßen aussieht:
int main() {
std::cout << Num<int>(1) + Num<double>(2.0);
return 0;
}
Das Ergebnis des Programms ist jedoch jetzt 3
. Während ich damit gerechnet habe 3.0
(vom Typ double
).
c++
class
templates
operator-overloading
Guillaume Racicot
quelle
quelle
Num<int>(1) + Num<double>(2.0);
ist dasselbe,Num<int>(1).operator+(Num<double>(2.0))
das Sie als Rückgabe eines Wertes vom Typ deklariert habenNum<int>
.value
.Antworten:
Dazu müssen Sie den Rückgabetyp ändern.
In Ihrem Code:
In der Tat können Sie in einer Klassenvorlage den Namen der Klasse ohne Vorlagenargumente eingeben, was dem Schreiben in gewisser Weise entspricht
Num<T>
.Ihre Funktion gibt immer den Typ des ersten Operanten zurück, unabhängig vom Typ der Addition.
Was Sie wollen, ist, diesen Typ aus der Addition abzuleiten:
Auf diese Weise ist es immer der richtige Rückgabetyp gemäß den C ++ - Operatorregeln.
quelle
-> Num<decltype(val + other.val)>
decltype(val + other.val)
und nichtNum<decltype(val + other.val)>
.Num{val + other.val}
operator+
sollte in Bezug auf seine Argumente symmetrisch sein. Es ist besser, als freie Funktion als als Elementfunktion implementiert zu werden, um diese Symmetrie explizit zu machen.Zum Beispiel (unter Verwendung des C ++ 14-Rückgabetypabzugs):
std::declval<T>()
ist für die Allgemeinheit da , wennT
und / oderU
nicht standardmäßig konstruierbar sind. Wenn Typen auf integrierte Typen wieint
und beschränkt sinddouble
, können sie durchT{}
oder ersetzt werdenT()
:Mit dem Abzug von Klassenvorlagenargumenten in C ++ 17 kann dies weiter vereinfacht werden:
quelle
auto
einen Rückgabetyp entfernen könnten . Das ist ziemlich cool.