return std::array
Ich bin die Implementierung einiger Klassen zur Darstellung von Zuordnungen (im mathematischen Sinne), d.h., f : R x R^n -> R^n. Ich würde gerne implementieren Sie eine abstrakte Basisklasse, die entweder:
1) Nimmt einen std::array als Referenz und ändert es
oder
2) liefert ein std::array (per Wert oder per Referenz -, nicht sicher?)
Die syntax von option 2 ist mehr wünschenswert, für mich, einfach weil ich denke, der code sieht mehr wie die Mathematik, die ich bin versucht zu stellen, aber ich möchte sichergehen, dass ich mich nicht unnötig kopieren und induzieren eine Reihe von unerwünschten overhead. Zum Beispiel, wenn ich einen hätte:
//Function f declaration
std::array<double, 4> f(double t, const std::array<double, 4> & x);
//Some code snippet that uses f
std::array<double, 4> x = {0.0, 1.0, 2.0, 3.0};
double t = 0.0;
std::array<double, 4> dxdt = f(t, x);
Wie kann ich ermitteln, ob eine Kopie wird durchgeführt auf der letzten Zeile, oder wie kann ich sicherstellen, dass es nicht passieren?
Innerhalb der definition von f(), was würde ich tun müssen (wenn überhaupt), um sicherzustellen, dass diese zurückgegeben wird, ohne einen Aufruf der copy-Konstruktor? Ich will halten die Nutzung einfach, sodass Kunden nicht brauchen, um verwenden Sie die Zeiger oder smart-Pointer, aber vielleicht ist dies notwendig?
Ich weiß, ich kann ändern Sie dies auf "void" zurückgeben und nur eines der Argumente sein, std::array dxdt, aber ich mag den Rückgabewert syntax besser, solange es keine Leistungseinbußen oder memory-leak-Probleme.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Es sollte etwas sein, Sie sollten nicht egal, denn die Optimierung von Kopien ist ein problem mit dem compiler. Aber die Compiler sind immer noch Turing-basierte Maschinen, die nicht erfinden Optimierung selbst.
So weit ich weiß, die meisten heutigen Compiler sich Verhalten, wenn eine Funktion:
Den compiler reserviert, die variable auf dem stack der Ort, wo es sein muss, werden bewertet, indem der Ausdruck, den Aufruf einer Funktion gehört.
Es wird keine Kopie erzeugt, die.
Wenn die Funktion mehrere Ausgänge Rückgabe verschiedenen Ausdrücke dieser -neben einigen besonderen Fällen - nicht gemacht werden kann.
So, in der Regel, wenn Sie haben sich wieder einige große Objekt, genauso erklären Sie es und stellen Sie sicher, dass alle return-Anweisungen zurück nur es.
dxdt = f(t, x);
. Wird die rvo noch kick?Keine Sorge: dies ist ein sehr häufiger Anwendungsfall, gut verstanden, der von Compilern. Stellen Sie sicher, dass Optimierungen obwohl. Eine weitere Sache, wenn Ihr array 4
double
lange, haben Sie wahrscheinlich wichtigere Dinge zu optimieren, bevor diese. Vergessen Sie nicht, dass eine Optimierung, bevor Sie wissen, Sie brauchen es (d.h. gemessen), ist böse.Nun, wenn Sie wirklich wollen, um sicherzustellen, gibt es keine Kopie, können Sie einen Blick auf den assembly code (wie, hängt von deinem compiler/tools).
Alternativ könnten Sie schreiben, eine Klasse von Ihrer eigenen, wo Sie etwas ausdrucken, im copy-Konstruktor und der Zuweisungs-operator, um sicherzustellen, Sie sind nicht genannt, aber Sie werden nicht in der Lage, das zu tun, mit
std::array<>
es sei denn, Sie leiten sich aus Ihr, was nicht erlaubt ist (es wird kompiliert und ausgeführt, wenn).Ich glaube, Sie brauchen sich keine sorgen über unnötige kopieren als compiler ist ziemlich gut in der Optimierung dieser Dinge. Es können RVO (Return Value Optimization) zu beseitigen unnötige Kopien. Und wenn Sie eine C++11 compiler unterstützt, das kopieren wird weiter reduziert durch die
move
Semantik.std::array<T,N>
, move-Semantik, sind wenig Wert. Move-Semantik nur helfen, wenn es Dereferenzierung (dynamisch zugewiesenen Speicher und Zeiger).Wenn Sie die Rückgabe durch Referenz, dann gibt es keine copy-Vorgang geht (wirklich, wir sind nur den Umgang mit 4 bytes, die eine Speicher-Adresse).
...können umgewandelt werden in:
...vorausgesetzt, dass der zurückgegebene Wert ist nicht einem lokalen stack-allokierten Variablen innerhalb der Funktion selbst (denn dann wird es eine dangling reference, nachdem zurückgegeben wird).
Würde der compiler wahrscheinlich tun dies automatisch, in einigen Fällen aber explizit, es ist besser, wie Sie sagen, Sie wollen gewährleisten kein kopieren auftreten.