Überladener ()-Operator mag nicht, obwohl in anderer Klasse möglich
-
Das inline zwingt dich dazu, die Methode so zu implementieren, dass sie potenziell geinlinet werden kann. Also musst du sie im Header definieren.
-
Hm schrieb:
Das inline zwingt dich dazu, die Methode so zu implementieren, dass sie potenziell geinlinet werden kann. Also musst du sie im Header definieren.
Habe ich denn das nicht hiermit gemacht:
double& operator () (unsigned); double operator () (unsigned) const;???
-
Das nennt man Deklaration.
Wenn du eine Methode inline bezeichnest, musst du dafür sorgen, dass sie im Header auch definiert ist, sonst kann sie nicht geinlinet werden.
-
Hm schrieb:
Das nennt man Deklaration.
Wenn du eine Methode inline bezeichnest, musst du dafür sorgen, dass sie im Header auch definiert ist, sonst kann sie nicht geinlinet werden.Mir ist schon klar, was Deklaration und Definition ist

Aber es scheint, ich hatte dich falsch verstanden. Du meinst also, ich solle die Funktionsdefinition in den Header aufnehmen?
Funktionieren tut das immerhin
Aber wieso funktioniert das Inlinen dann bei der Matrix (mit abgesehen vom Klassennamen identischen Deklarationen), wenn ich die Funktion in der cpp-Datei definiere?
-
Chewie83 schrieb:
Aber wieso funktioniert das Inlinen dann bei der Matrix (mit abgesehen vom Klassennamen identischen Deklarationen), wenn ich die Funktion in der cpp-Datei definiere?
Rufst du den Operator irgendwo auf? Dem Compiler reicht die Deklaration, der Linker beschwert sich über fehlende Definitionen erst wenn sie benötigt werden...
-
Ja, ich ruf das ganze auf.
Hm, könnte es vielleicht sein, dass der Compiler im ersten Fall entscheidet, dass die Methode nicht geinlinet wird. Der Linker kommt nun erst nach dieser "Optimierung" und für ihn ist es so, als wäre die Methode nicht inline.Wie auch immer, wenn ich mal viel Zeit habe, muss ich mal eingehend mit den ganzen Mechanismen in C++ beschäftigen. Mein persönlicher Respekt an die, die die Eigenheiten dieser Sprache verstehen!
-
mit dem inline darf das nichts zu tun haben und im header muss sie auch nicht definiert sein. member funktionen haben immer external linkage, und die definition muss der compiler nur dann sehen, wenn er vorher eine inline deklaration gesehen hat. das ist hier aber nicht der fall, die einzige deklaration ist die in der klassendefinition und die enthält kein inline. der fehler kann nicht im geposteten code allain liegen.
nebenbei - wieso wird in einem const overload eigentlich aus T& immer T statt const T& ? das ist unintuitiv und hat einige merkwürdige konsequenzen (z.b. mit dem & operator - der geht nicht bei built-in rvalues, und bei anderen typen ist der zeiger unbrauchbar; hat man den non-const overload erwischt, klappt alles).
-
camper schrieb:
nebenbei - wieso wird in einem const overload eigentlich aus T& immer T statt const T& ?
Vielleicht hat der OP ja Angst vor const_cast.
Ich verwender aber auch eher 'const T&'.
-
camper schrieb:
nebenbei - wieso wird in einem const overload eigentlich aus T& immer T statt const T& ? das ist unintuitiv und hat einige merkwürdige konsequenzen (z.b. mit dem & operator - der geht nicht bei built-in rvalues, und bei anderen typen ist der zeiger unbrauchbar; hat man den non-const overload erwischt, klappt alles).
Meinst du das:
double& operator () (unsigned); double operator () (unsigned) const;Das hab ich von http://www.parashift.com/c++-faq-lite/operator-overloading.html#faq-13.10
-
Es ging weniger um den () Operator, sondern um den Rückgabewert. Die const Version kannst du auch wie folgt schreiben:
const double& operator () (unsigned) const;Gerade wenn du nicht-triviale Rückgabewerte hast, kann das ein Vorteil sein, weil der Compiler hier besser optimieren kann.
-
Danke, dann werd ich das mal probieren.
Welche Auswirkung hat das dann auf die Semantik?
-
Für den Nutzer gar keine, aber er spart sich damit einen Aufruf des Copy-Ctors und Dtors
"double operator() const" kopiert den Wert aus deinem Vektor in eine temporäre Variable, die dann der Zielvariablen zugewiesen wird, und löscht hinterher die temporäre Variable. "const double& operator() const" weist direkt aus dem Vektor der Zielvariablen zu.
-
ein referenz ist ein lvalue, gibts du irgendetwas anderes zurück ist es ein rvalue. der unterschied bei builtins ist hinsichtlich dessen, was du tun kannst, nicht besonders gross. allerdings, gerade bei einer matrix-klasse, die mir verspricht, dass ihre daten intern in einem array gespeichert werden, kann es nützlich sein den adress-operator zu benutzen um iteratoren für standardalgorithmen zu bekommen, falls die klasse selbst keine iteratoren zur verfügung stellt. den adress-operator kannst du aber nur auf lvalues anwenden - und für fundamentale typen gibt es keine möglichkeit aus einem rvalue wieder ein lvalue zu machen.
bei klassen sieht das ganze etwas anders aus. innerhalb einer klasse ist *this stets ein lvalue - du kannst aber memberfunktionen auch mit rvalues benutzen...