falscher operator aufruf
-
ersteinmal alle relevanten information zur klasse
template <class t, unsigned int n> class T { private: t data[n]; //datenfeld public: operator const t* () const; // cast in (t*) T<t,n> operator - (const T<t,n>& r); // - operator //... }; //... class T2: virtual public T<float, 3> { //... }; //... T2 var1, var2; //... T2 var3 = var1 - var2; //Anweisung mit falschem Operator aufrufdas problem was bei mir jetzt auftritt ist das er nicht den -operator aufruft sondern den cast-operator und ich hab keinen blassen warum. das interessante ist wenn ich den -operator aus der klasse auslagere, also
template <class t, unsigned int n> T<t,n> operator - (const T<t,n>& l, const T<t,n>& r); // - operator ausgelagertdann wird der -operator bei der anweisung aufgerufen.
vllt hat ja jemand eine idee. danke schonmal im voraus.
-
Darf man vielleicht erfahren, was es an Konstruktoren in Deiner TC gibt?
Ich vermute mal da gibts sowas wie
T(const t* pt);Wenn ja, mach den mal explicit.
-
naja, implizit gibts diesen vllt schon, da ich einen copy-constructor definiert habe.
T(const T<t,n>& src);
-
Hi,
wie der Name schon andeutet, hilft Dir ein impliziter Konstruktor nicht weiter, wenn Du ein "explicit" (keyword) brauchst

Gruß,
Simon2.
-
FreakyBKA schrieb:
naja, implizit gibts diesen vllt schon, da ich einen copy-constructor definiert habe.
T(const T<t,n>& src);Der Konstruktor passt eigentlich nicht.
Ich hatte schon an sowas wie
T(const t* pt)gedacht.
Das gibt dann mit dem Cast-Operator nämlich
T2 var3(float* + float*); /* float* implizit durch Cast-Operator fuer var1 und var2 erzeugt, und in passenden Konstruktor T2(float* pt) eingesetzt. */Ich habe die Casts hier mal extra explizit ausgeführt. In Deinem würde das natürlich alles implizit passieren.
Der resultierende Zeiger zeigt zwar vermutlich ins Nirvana, aber trotzdem ist das (sofern ich es nicht verpeilt habe) ein gültiger Ausruck.
Mach entweder den Cast oder den Konvertierungskonstruktor (sofern er wirklich existiert) mal explicit.
Der Cast-Operator sollte eigentlich auch zwei mal aufgerufen werden. Ist das so?PS: Ich habe keinen Schnall, ob das wirklich so abläuft. Das ist nur eine vage Vermutung.
-
Poste doch mal alle Konstruktoren und Konvertierungsoperatoren von T und T2 sowie die Deklaration aller freien Operatoren, die für T oder T2 gefunden werden können.
Zeiger kann man im Übrigen nicht addieren oder subtrahieren, wohl aber Zeiger und integrale Ausdrücke.
-
Ja, da hast Du allerdings recht @camper.
Das gesamte Interface der Klasse wäre allerdings schon hilfreich.
-
Das war Mist, bitte löschen.
-
das was ich da geschrieben habe ist eine vereinfachte und reduzierte variante der tatsächlichen klassen (über 100 zeilen). deswegen sind auch die namen nur als T bzw T2 gegeben um es auf das wesentliche zu reduzieren.
für T gibts folgende Konstruktoren und interne Operatoren:
T(); T(const T<t, n>& src); void operator = (const T<t, n>& src); operator const t* () const; T<t,n> operator - (const T<t,n>& r);für T2 gibts folgende Konstruktoren und interne Operatoren:
T2(float x = 0, float y = 0, float z = 0); T2(const T<float, 3>& src); void operator = (const T<float, 3>& src);und T2 ist wie gesagt von T abgeleitet also:
class T2 : virtual public T {//... };und ja er ruft bei der Anweisung zweimal den Cast-Operator auf und scheint die dann voneinander abzuziehen, warum auch immer das geht.
-
jetzt war ich selbst ein wenig verwirrt. Subtrahieren kann man zwei Zeiger schon: p1-p2== distance(p2,p1) ... naja, Konvertierungsoperatoren sind sowieso ziemlich böse, wenn man nicht sehr aufpasst.
Ich behaupte allerdings, das hier noch eine weiter Deklaration stört. Jedenfalls ruft mein Compiler hier nicht den Konvertierungsoperator auf.
#include <iostream> using namespace std; template <class t, unsigned int n> class T { private: t* data[n]; public: T() { cout << "T::T()" << endl; } T(const T<t, n>& src) { cout << "T::T(const T&)" << endl; } void operator = (const T<t, n>& src) { cout << "void T::operator=(const T&)" << endl; } operator const t* () const { cout << "T::operator const t*()" << endl; return data; } T<t,n> operator - (const T<t,n>& r) { cout << "T T::operator-(const T&)" << endl; return *this; } }; class T2: virtual public T<float, 3> { public: T2(float x = 0, float y = 0, float z = 0) { cout << "T2::T2(float=0,float=0,float=0)" << endl; } T2(const T<float, 3>& src) { cout << "T2::T2(const T<float,3>&)" << endl; } void operator = (const T<float, 3>& src) { cout << "coid T2::operator=(const T<float,3>&)" << endl; } }; int main() { T2 var1, var2; T2 var3 = var1 - var2; }
-
Was mich da wundert, ist, daß es keinen passenden Konstruktor gibt. Ein entsprechender Konstruktor müsste auch einen Pointer übernehmen und keine Objektreferenz.
Probier als Workarround doch mal, den Cast selbst als explicit zu deklarieren.
-
Der folgende Konstruktor wird benutzt:
T2(float x = 0, float y = 0, float z = 0);Die Differenz der beiden Zeiger liefert ein Int, und der passt zu dem oben stehenden Konstruktor. Irgendwie ziemlich böse.
Wieso dabei aber das ganze implzite Geknispel dem direkt passenden Wert vom Subtraktions-Operator vorgezogen wird, ist mir schleierhaft.
Setzte in dem obenstehenden Konstruktor mal eine Ausgabe ein. Ich schätze mal der wird aufgerufen.
-
ja das meinte ich ja, mein fehler, der konvertiert erst var1 und var2 in t* und ruft dann den constructor mit x,y,z auf.
wie definiere ich denn das zeugs explizit? und was genau bewirkt das?
-
explicit als Schlüsselwort mit rein (Google hilft
)
Mir ist nur Schleierhaft, wieso das Casten und implizite Umwandeln von int nach float dem direkt passenden operator- und dem Copy-Konstruktor vorgezogen wird. Bei mir ist das nicht so.
-
Tachyon schrieb:
explicit als Schlüsselwort mit rein (Google hilft
)
Mir ist nur Schleierhaft, wieso das Casten und implizite Umwandeln von int nach float dem direkt passenden operator- und dem Copy-Konstruktor vorgezogen wird. Bei mir ist das nicht so.es ist aucht nicht so. Wenn das ein vereinfachtes Beispiel ist, gehe ich davon aus, dass sich beim Vereinfachen ein Fehler eingeschlichen hat.
-
beim vereinfachen ist kein fehler passiert, habe es gerade nochmal durchgeschaut.
also ich hab mir jetz mal das mit explicit angeschaut, allerdings hab ich jetz ein anderes problem. nämlich:T2 var3 = var2 - var1;das funktioniert jetzt nicht mehr, warum auch nicht?
weil es gibt ja den copy-constructor über die klasse T, der das eigentlich abwickeln sollte.
-
FreakyBKA schrieb:
beim vereinfachen ist kein fehler passiert, habe es gerade nochmal durchgeschaut.
Dann sollte es sich aber nicht anders verhalten. Welchen Compiler setzt du denn ein?
also ich hab mir jetz mal das mit explicit angeschaut, allerdings hab ich jetz ein anderes problem. nämlich:
T2 var3 = var2 - var1;das funktioniert jetzt nicht mehr, warum auch nicht?
weil es gibt ja den copy-constructor über die klasse T, der das eigentlich abwickeln sollte.Was heißt funktioniert nicht? Fehlermeldung des Compilers? wenn ja, welche? Im Übrigen sind hier zwei Konstruktoren von T2 beteiligt und die von T eigentlich nur als Teil dieser anderen Konstruktoren.
-
als compiler hab ich den VC++ Express 2005.
error C2440: 'initializing' : cannot convert from '__w64 int' to 'T2' Constructor for class 'T2' is declared 'explicit'weil ich jetzt den einen constructor explizit gemacht habe
explicit T(float x = 0, float y = 0, float z = 0, float v = 0);also er konvertiert var1 und var2 immernoch in (t*)
also gedacht war das ja so, das ich die operatoren in T definiere und in T2 mitverwenden kann, weswegen bei var1 - var2 eigentlich was temporäres von Typ T<float, 3> rauskommen sollte und das sollte dann als argument für den anderen constructor bei der Klasse T2 genommen werden.
das problem ist außerdem noch, das wenn ich statt
T2 var3 = var1 - var2;jetzt
T2 var3(var1 - var2);schreibe dann nimmt er auch den expliziten constructor von T2 und subtrahiert wieder die zeiger voneinander.

-
Was sagt denn der Compiler, wenn du den operator t* weglässt? (btw, wozu benötigst du den überhaupt?)
-
FreakyBKA schrieb:
beim vereinfachen ist kein fehler passiert, habe es gerade nochmal durchgeschaut.
also ich hab mir jetz mal das mit explicit angeschaut, allerdings hab ich jetz ein anderes problem. nämlich:T2 var3 = var2 - var1;das funktioniert jetzt nicht mehr, warum auch nicht?
weil es gibt ja den copy-constructor über die klasse T, der das eigentlich abwickeln sollte.Ich wage mal zu behaupten, daß dann Dein Copy-Konstruktor nicht in Ordnung ist, bzw. nicht existiert. Oder aber Dein operator- gibt einen falschen Typ zurück.
//falscher Parameter oder nicht vorhanden T2(const T<float, 3>& src); //bzw. //gibt falschen Typ zurück. T<t,n> operator - (const T<t,n>& r);Offensichtlich scheint die Adressdifferenz, die durch das Subtrahieren der Zeiger entsteht, die einzige Variante zu sein, für die ein gültiger Konstruktor existiert (der jetzt aber explicit deklariert wurde).
-
also var1 - var2 sollte ein ergebnis vom typ T<float, 3> liefern, da der Subtraktions-Operator von T aufgerufen werden sollte und für T2 gibt es ja den Konstruktor
T2(const T<float, 3>& src);den Cast in (t*) brauch ich in dem programm, weil es bei mir funktionen gibt die diesen typ als argumenttyp haben, aber das ist ja für das problem irrelevant. der cast liefert quasi den zeiger der internen variable
t data[n];das sind aber wie gesagt alles nur details.