Konzept Multiplikationsoperator einer Matrix
-
EOutOfResources schrieb:
Nein:
lapack_matrix&& lapack_matrix::operator*(lapack_matrix &rhs) constWie kommst du nur auf die Idee, eine RValue Referenz auf eine lokale Variable zurückzugeben. RValue Referenzen _sind_ auch nur Referenzen! Eine ganz normale Wert-rückgabe, allerdings mit move, gehört hier her.
Move-Semantiks bedeutet, dass es einen Move Ctor gibt, der Move op = kann über den Move Ctor sehr einfach implementiert werden, indem man das Objekt per Value nimmt.
-
314159265358979 schrieb:
EOutOfResources schrieb:
Nein:
lapack_matrix&& lapack_matrix::operator*(lapack_matrix &rhs) constWie kommst du nur auf die Idee, eine RValue Referenz auf eine lokale Variable zurückzugeben. RValue Referenzen _sind_ auch nur Referenzen! Eine ganz normale Wert-rückgabe, allerdings mit move, gehört hier her.
Move-Semantiks bedeutet, dass es einen Move Ctor gibt, der Move op = kann über den Move Ctor sehr einfach implementiert werden, indem man das Objekt per Value nimmt.
Wäre dir für ein Beispiel sehr dankbar.
-
Move-Konstruktor:
Object(Object&& other) : some_variables(other.some_variables) { other.some_variables = some_default_value; }Hier werden die Ressourcen von other "geklaut". Wichtig ist dabei, dass other weiterhin ein gültiges Objekt ist, mit dem gearbeitet werden kann.
op =:
Object& operator = (Object rhs) // ganz normale Werte-übergabe { rhs.swap(*this); return *this; }Diese operator = kann sowohl kopieren, als auch moven. Er wird deswegen auch gerne als "unified assignment-operator" bezeichnet. Wenn ein R-Value übergeben wird, wird das rhs-Objekt move-constructed, sprich, der Move-Konstruktor wird für rhs aufgerufen. Wird ein L-Value übergeben, dann wird der normale Copy-Ctor aufgerufen.
Mit diesem assignment operator entfällt auch der nervige Check, ob other == *this, außerdem ist er Excepion-Save, ein swap() sollte niemals etwas werfen.
-
CStoll schrieb:
Da wäre es eventuell eine Idee, deine Matrix-Klasse mit Referenzzhälung und copy-on-write Funktionalität auszustatten. (d.h. der Speicher wird erst wirklich kopiert, wenn einer der Verwender etwas daran ändern will)
Oder nur C++98-Move-Semantik à la
auto_ptr, sofern man keine Wertsemantik benötigt. Ist noch etwas günstiger alsintrusive_ptr, was hier ja im Prinzip nachgebaut wird.314159265358979 schrieb:
Eine ganz normale Wert-rückgabe, allerdings mit move, gehört hier her.
Ohne
std::move(), eine funktionslokale Variable existiert nicht länger. Move-Konstruktoren können implizit generiert und aufgerufen werden.Aber heutige Compiler können schon recht gut RVO. Allerdings muss man ein paar Dinge beachten, um die Optimierung nicht zu verhindern.