Referenz zurückgeben?
-
Edit:
Ich brauch eine Brille Shade hat recht deine Funktion returned eine Kopie.
Das was du mit der Referenz machst ist komplett unsinnig.
Was möchtest Du damit erreichen?~~Das ist wie du richtig erkannt hast eine lokale Referenz die, außerhalb des Scopes ("{" "}") nicht mehr gültig ist.
Mit anderen Worten, dass ist ein Fehler man gibt niemals Referenzen auf lokale Objekte zurueck.
Ein int zu kopieren, kostet nichts es dürfte sogar genauso teuer sein die Referenz auf ein int zurückzugeben wie das int zu kopieren.~~
-
Shade Of Mine schrieb:
Du gibst keine Referenz zurück, also alles OK.
Ok super.
Ruvi schrieb:
Edit:
Ich brauch eine Brille Shade hat recht deine Funktion returned eine Kopie.
Das was du mit der Referenz machst ist komplett unsinnig.
Was möchtest Du damit erreichen?Ist ziemlich stark gekürzt, hab nur in einem code gesehen dass jemand sowas wie
vector Get() { return GetVector(); }macht wobei GetVector eine Referenz zurückgibt, da wollte ich auf Nummer sicher gehen

-
int Get()
und
vector Get()
liefern beide eine Kopie - also KEINE Referenz
wenn
int& Get()
schreiben wuerdest gibts Warnungen
-
Es kann gerade auch bei einem vector sehr viel Sinn machen mit einer Referenz zu arbeiten. Gerade wenn viele Elemente enthalten sind, dann will man nicht unnötig kopieren. Wenn also die Gültigkeit sichergestellt ist, dann kann man auch mit einer Referenz weiterarbeiten.
Auch beim Befüllen sollte man darauf achten:
std::vector<int> Fill() { std::vector<int> v; // Füllen // Rückgabe einer Kopie(!). Eine Referenz wäre hier fatal! return v; }vs
void Fill(std::vector<int>& v) { // Füllen }
-
hgjghj schrieb:
Es kann gerade auch bei einem vector sehr viel Sinn machen mit einer Referenz zu arbeiten. Gerade wenn viele Elemente enthalten sind, dann will man nicht unnötig kopieren.
Und genau aus diesem Grund gibt es die (N)RVO, die es dem Compiler erlaubt, sämtliche Kopien bei der Wertrückgabe zu eliminieren.
Just trust the compiler.
-
Das ist aber eben auch nicht immer möglich und es tut sicher nicht weh es über eine Referenz zu lösen. Mehraufwand sehe ich hier nämlich nicht.
-
Referenz auf nen vector zurückgeben macht mMn. hauptsächlich dann Sinn wenn der vector eben gerade keine lokale Variable bzw. Parameter ist.
Also z.B. nen Member.
Wobei es gerade dann auch meist ein wenig unsauber/gefährlich ist.
-
fghfgh schrieb:
Das ist aber eben auch nicht immer möglich und es tut sicher nicht weh es über eine Referenz zu lösen. Mehraufwand sehe ich hier nämlich nicht.
Es macht eine deutlich hässlichere und unnatürliche Syntax.
Und mit C++11 wird so oder so gemoved, da macht das minimalen Unterschied, ob die Optimierung angewendet wird oder nicht.
Vertraue einfach dem Compiler.
-
In welchen Fällen sind denn weder NRVO noch RVO nicht möglich?
* Rückgabe von Parametern
Sonst noch was?
Wie sieht's mit der Rückgabe von Rückgabewerten aus?BTW: Wenn man es wirklich in C++03 braucht, kann man doch eigentlich immer swap verwenden um doch wieder von der NRVO zu profitieren, nicht?
Also
vector Foo(/*was auch immer*/) { ... vector rv; rv.swap(/*was auch immer*/); return rv; // NRVO, yeehah }
-
Super Lösung!
--- Rest gestrichen - falsch gedacht ---

-
void fill(vector<T> &vref) { // vref füllen }So, kein Streit ob RVO oder Referenzzurück geben.
-
Artchi schrieb:
void fill(vector<T> &vref) { // vref füllen }So, kein Streit ob RVO oder Referenzzurück geben.
Das ist doch, worüber diskutiert wurde.
Das ist nicht notwendig, es gibt RVO.
-
Nathan schrieb:
Artchi schrieb:
void fill(vector<T> &vref) { // vref füllen }So, kein Streit ob RVO oder Referenzzurück geben.
Das ist doch, worüber diskutiert wurde.
Das ist nicht notwendig, es gibt RVO.Obwohl es RVO gibt finde ich, dass von Artchi beschriebene Konstrukt richtiger als dein Ansatz Nathan.
Man sieht im Code exakt was passiert und verlässt sich nicht auf implizite Compiler-optimierungen die den Quatsch den man da hingeschrieben hat schon berichtigen werden.
Außerdem gibt es Fälle in denen RVO nicht greift und das muss man auch jedes mal bedenken.
Bsp.:
- return von Parameter
- im return statement eine if/else ist
- return of const Objekt (oder war das bei nur bei move?!)
- Function call im return statement
- Wenn der return type volatile oder atomic istDie Liste hat keinen 100% Anspruch auf Richtigkeit habe ich aus dem Gedächtnis runtergeschrieben ich hoffe ich konnte mich richtig erinnern.
-
Call by Reference ist aber etwas komplett anderes als (N)RVO und sehr oft ist das ja nicht mal substituierbar.