Problem mit Templates
-
Hey Leute,
ich versuche gerade ca folgendes (Vorsicht, die Funktion zur Überladung des "+" ist ist nicht kompilierbar und soll meine Gedankengänge etwas verdeutlichen)
template <typename T> class A { public: T x; A(int init) : x(init) {} }; template <typename T, typename U, typename Z> A<typeid(tmp).name> operator+(A<T> lhs, A<U> rhs) { auto tmp = lhs.x + rhs.x; return A<typeid(tmp).name>(tmp); } int main() { A<int> a(1); A<float> b(2.1f); std::cout << (a+b).x << std::endl; return 0; }Das Problem ist folgendes, ich möchte, falls ich wie Beispielsweise in der Main-Funktion ein A<int> und ein A<float> addiere, final ein A<float> erhalte.
Weiß einer von euch wie man das elegant realisieren kann, dass dies allgemein für alle Standardtypen die sich implizit ineinander casten lassen funktioniert?
Gruß

-
Nur so ne Idee, nicht getestet:
template <typename U, typename V> auto operator +(A<U> lhs, A<V> rhs) -> A<decltype(lhs.x + rhs.x)> { return lhs.x + rhs.x; }
-
Wenn das von dot nicht geht, kannst du die andere C++11-Lösung probieren:
template <typename T, typename U, typename Z = decltype(std::declval<T>()+std::declval<U>())> A<Z> operator+(A<T> lhs, A<U> rhs) { return A<Z>(lhs.x + rhs.x); }Wenn du kein C++11 hast, geht es auch, aber dann wirds wüst.
-
Vielen Dank für eure Hilfen

Leider bekomme ich für die Version von "einfachmalso " den Fehler, dass + für die Operanden nicht definiert sein soll

Weiß zufällig einer warum?Die andere Version von "dot" kompiliert zwar, aber gibt eine "3" aus anstatt "3.1."
Was genau macht "-> A<decltype(lhs.x + rhs.x)>" ?Gruß

-
MatheStein schrieb:
Was genau macht "-> A<decltype(lhs.x + rhs.x)>" ?
Es setzt den Rückgabetyp der Funktion auf den Typ des Ausdrucks lhs.x + rhs.x, bei int und float sollte das float sein.
Das gibt bei mir wie erwartet 8.3 aus:template <typename T> struct A { T x; A(T x) : x(x) {} }; template <typename T, typename U> auto operator + (const A<T>& lhs, const A<U>& rhs) -> A<decltype(lhs.x + rhs.x)> { return A<decltype(lhs.x + rhs.x)>(lhs.x + rhs.x); } int main() { A<int> a1(5); A<float> a2(3.3f); std::cout << (a1 + a2).x << '\n'; }
-
Was wäre denn der Unterschied zu
template <typename U, typename V> A<decltype(lhs.x + rhs.x)> operator +(A<U> lhs, A<V> rhs) -> { return lhs.x + rhs.x; }Gruß

-
Siehe mein Edit.
Der Unterschied ist, dass es nicht kompiliert, weil lhs und rhs da noch gar nicht bekannt sind.
-
MatheStein schrieb:
Die andere Version von "dot" kompiliert zwar, aber gibt eine "3" aus anstatt "3.1."
Wie sieht der Code dazu aus?
MatheStein schrieb:
Was genau macht "-> A<decltype(lhs.x + rhs.x)>" ?
decltype()liefert den Typ eines Ausdrucks.
A<decltype(lhs.x + rhs.x)>entspricht alsoA<Was auch immer lhs.x + rhs.x produziert>.
Die Syntax mitautound dem->gefolgt von einem Typ ist eine alternative Möglichkeit den Rückgabetyp einer Funktion zu deklarieren. Vorteil dabei ist, dass hinter der Parameterliste die Parameterlhsundrhsbekannt sind und ich daher überdecltype()dem Compiler sagen kann, dass er den passenden Typ doch bitte selbst rausfinden soll.
-
Danke für deine Antwort

Wie nennt man das Konzept mit dem Pfeil, bzw was muss man dafür googlen?
Gruß

-
-
Jap. Man spricht dabei von einem "trailing-return-type".
-
Danke
