C++ Template-Programmierung: Unterschiedliche Rückgabewerte bei Überladung des "+ Operators"
-
Hallo alle zusammen!
Ich habe folgendes Problem und hoffe, dass Ihr mir hier vielleicht weiterhelfen könntet. Es geht um folgendes:
Ich möchte mir eine Vektoren-Klasse (Vektor im Sinne der Mathematik) schreiben, welche im Moment erst mal einen Punkt im 3-dimensionalen Raum repräsentieren, sowie die Addition zweier 3-dimensionaler Vektoren, sowie einen cast zulassen soll. Der Rest kommt dann im Nachhinein noch dazu^^. Da ich mich aktuell mit der Programmierung mit Templates auseinandersetze, dachte ich, dass dies eine gute Übung hierfür wäre und wollte die Klasse als Template aufbauen. Mein bisheriger Code sieht folgendermaßen aus:
Hier die Vektor-Klasse in ihrer bisherigen Ausführung:
Vec3.hpp
#pragma once template <typename T> class Vec3 { public: Vec3() : x(0), y(0), z(0) { } Vec3(T x, T y, T z) : x(x), y(y), z(z) { } template <typename U> Vec3 operator+(const Vec3<U>& other) { Vec3 result; result.x = this->x + other.x; result.y = this->y + other.y; result.z = this->z + other.z; return result; } template <typename U> operator Vec3<U>() const { Vec3<U> result; result.x = static_cast<U>(this->x); result.y = static_cast<U>(this->y); result.z = static_cast<U>(this->z); return result; } T x, y, z; };
Hierbei gibt es jetzt folgendes Problem wie in der nachfolgenden Main.cpp zu sehen:
Main.cpp
#include "Vec3.hpp" int main() { Vec3<int> vec_1(1, 2, 3); //Funktioniert. Vec3<float> vec_2(1.5f, 2.5f, 3.5f); //Funktioniert. Vec3<float> vec_3 = vec_1 + vec_2; //Falsches Ergebnis... system("pause"); return 0; }
Das Anlegen der Vektoren funktioniert ohne Probleme, aber die Addition liefert ein falsches Ergebnis zurück. Hier erhalte ich folgende Werte für vec_3:
vec_3.x = 2
vec_3.y = 4
vec_3.z = 6An sich kann ich das Ergebnis schon nachvollziehen, nur hätte ich gerne folgendes Ergebnis:
vec_3.x = 2.5
vec_3.y = 4.5
vec_3.z = 6.5Ich habe auch schon etwas rum probiert, nur funktioniert nichts, da die Addition immer ein Ergebnis des Typs des ersten Summanden zurückgibt, im obigen Beispiel also Vec3<int>.
Meine Frage wäre nun, kann man dieses Problem mit Templates in den Griff bekommen? Gibt es hier irgend eine Technik, welche ich übersehe?
Wie gesagt bin ich noch ziemlich neu in der Programmierung mit Templates, weshalb ich wohl auch viele wichtige Dinge und Fähigkeiten einfach noch übersehe und nicht kann. Falls Ihr übrigens weitere Vorschläge habt bezüglich meines Codes, bin ich auch dafür jederzeit offen.
An dieser Stelle schonmal vielen vielen Dank!
Außerdem bin ich ziemlich neu hier im Forum, also falls ich bei meinem Beitrag irgendwas übersehen haben sollte, im falschen Forum bin oder ich ihn besser formatieren sollte usw dann sagt einfach Bescheid
Gruß
Patrick
-
Dein
operator+
gibt ein Objekt vom Typ des linken Summanden zurück, welcher bei dir den Elementtypint
hat. Dass du damit einen Vektor von Fließkommazahlen initialisierst, ist irrelevant.Du solltest den operator+ global machen, und den Elementtyp des Ergebnisses mittels
std::common_type
bestimmen.
-
Vielen Dank! Jetzt funktioniert alles so wie es soll
-
Hat
common_type
in diesem Beispiel einen Vorteil gegenüberdecltype(T() + U())
?
-
hustbaer schrieb:
Hat
common_type
in diesem Beispiel einen Vorteil gegenüberdecltype(T() + U())
?decltype(std::declval<T>() + std::declval<U>())
wäre hier in der Tat besser, da es in Fällen funktionieren kann, in denencommon_type
eben nicht funktioniert. Insbesondere dann, wennT
undU
Typen ohne ein besonderes Verhältnis zueinander sind. Mein Fehler.