Operatoren und Implizite Konversion
-
Hallo
Ich habe das Problem, dass bei unten stehender Klasse die implizite Konversion bei den externen operatoren nicht funktioniert. Eigentlich wollte ich erreichen, dass man einen Vector direkt mit einer Zahl z.B. multiplizieren kann, ohne dass es eine Rolle spielt, auf welcher seite die Zahl steht. Leider weigert sich VC++ 2005 die Zahl in einen Vector umzuwandeln. Weiss jemand wieso?
Gruss
Stefan
#ifndef VECTOR_H #define VECTOR_H template<typename T> struct Vector { T x, y, z; Vector(T val = 0) { this->x = val; this->y = val; this->z = val; } Vector(T x, T y, T z) { this->x = x; this->y = y; this->z = z; } Vector& operator += (const Vector &vec) { this->x += vec.x; this->y += vec.y; this->z += vec.z; return *this; } Vector& operator -= (const Vector &vec) { this->x -= vec.x; this->y -= vec.y; this->z -= vec.z; return *this; } Vector& operator *= (const Vector &vec) { this->x *= vec.x; this->y *= vec.y; this->z *= vec.z; return *this; } Vector& operator /= (const Vector &vec) { this->x /= vec.x; this->y /= vec.y; this->z /= vec.z; return *this; } }; template<typename T> Vector<T> operator + (const Vector<T> &v1, const Vector<T> &v2) { return Vector<T>(v1) += v2; } template<typename T> Vector<T> operator - (const Vector<T> &v1, const Vector<T> &v2) { return Vector<T>(v1) -= v2; } template<typename T> Vector<T> operator * (const Vector<T> &v1, const Vector<T> &v2) { return Vector<T>(v1) *= v2; } template<typename T> Vector<T> operator / (const Vector<T> &v1, const Vector<T> &v2) { return Vector<T>(v1) /= v2; } #endif
-
Hi,
hmmmm lange Geschichte, ist wegen den Templates so. Hatten wir in letzter Zeit schon nen paar Mal hier. Ich suche mal nach nem Link, damit ich nichts schreiben muss
-
Siehe da : http://c-plusplus.net/forum/viewtopic-var-t-is-161613-and-highlight-is-.html Ich hatte auch mal diese Frage gestellt

-
Und hier auch noch nen Link, wo du auch direkt siehst wie es bei dir aussehen musst, damits funktioniert, wenn du noch eine zusätzliche Erklärung brauchst, dann kriegste wieder ein paar Links

-
Für Parameter, die zur Deduktion von Templateparametern genutzt werden, sind die meisten impliziten Konvertierungen (und selbstdefinierte sowieso) unterdrückt. Etwas Anderes würde zu viele Mehrdeutigkeiten produzieren; aus dem gleichen Grunde kann eine implizite Konvertierungssequenz immer nur höchtens einen selbstdefinierten Operator/Konstruktor enthalten. Wie so oft gibt es mehr als eine Möglichkeit, das Problem zu umgehen:
1. an Stelle von Templates verwenden wir normale Funktionen, und überladen für jeden Templateparameter:template<typename T> struct Vector { ... friend Vector operator + (const Vector &v1, const Vector &v2) { return Vector(v1) += v2; } ... };Im Allgemeinen sollte man mit diesem Verfahren vorsichtig sein, weil das komplette Set überladener Funktionen davon abhängt, welche Templates instantiiert wurden. In diesem Falle sehe ich da allerdings keine Probleme.
2. wir deduzieren verschiedene Templateparameter und verlassen uns darauf, dass für fehlerhafte Paramater das Instantiieren fehlschlägt:
template<typename T, typename U> Vector<T> operator + (const U &v1, const Vector<T> &v2) { return Vector<T>(v2) += v1; } template<typename T, typename U> Vector<T> operator + (const Vector<T> &v1, const U &v2) { return Vector<T>(v1) += v2; } template<typename T, typename U> Vector<T> operator + (const Vector<U> &v1, const Vector<T> &v2) { return Vector<T>(v1) += v2; }3. etwas verfeinert könnten wir auch einen Parametr zwar vom Templateparameter abhängig machen, aber so, dass ein nicht deduzierbarer Kontext ensteht:
template<typename T> struct Identity { typedef T type; }; // die einfachsten Konstrukte sind oft sehr nützlich template<typename T> Vector<T> operator + (const typename Identity<Vector<T> >::type &v1, const Vector<T> &v2) // Linker Parameter ist nicht deduzierbar { return Vector<T>(v2) += v1; } template<typename T, typename U> Vector<T> operator + (const Vector<T> &v1, const typename Identity<Vector<T> >::type &v2) { return Vector<T>(v1) += v2; } template<typename T> Vector<T> operator + (const Vector<T> &v1, const Vector<T> &v2) { return Vector<T>(v1) += v2; }das sind die Möglichkeiten, die mir unmittelbar einfallen - sicher gibt es noch mehr
-
Danke euch beiden!

-
Uuups:
KasF schrieb:
Und hier auch noch nen Link, wo du auch direkt siehst wie es bei dir aussehen musst, damits funktioniert, wenn du noch eine zusätzliche Erklärung brauchst, dann kriegste wieder ein paar Links

http://www.parashift.com/c++-faq-lite/templates.html#faq-35.16
-
hi,
KasF, Ubr und hustbaer haben mir vor kurzem bei einem ähnlichen Problem sehr geholfen. Vielleicht nützen dir einige Details meiner Matrixklasse (an der ich gerade wieder rumprogrammiere), denn die Operatorüberladung funktioniert nun.http://www.c-plusplus.net/forum/viewtopic-var-t-is-182721.html
vg tesu