Pass by value oder const reference

10/10/2015 12:01 th0rex#16
Quote:
Originally Posted by _Roman_ View Post
Heißt das also, dass ich mit std::move und nem normalen QString Parameter arbeiten sollte, wenn Qt den String kopiert? Verlier grad etwas den Überblick bei den ganzen Informationen
"For direct connections, it is recommended that the values are passed by const reference to avoid needless copies. For queued connections Qt will make a copy no matter how you pass the arguments" sagt doch eigentlich alles. Nimm einfach ne konstante Referenz und kopier die. Mach dir nicht so viel Gedanken über diesen einen String, man wird kaum einen Unterschied merken.
10/11/2015 00:00 Padmak#17
Quote:
Originally Posted by C0untLizzi View Post
Dann ist der typ von dem Parameter eigentlich std::string&&. Da wir die Funktion aber nur ein const std::string& annehmen lassen, wird diese Variante aufgerufen und wir bekommen keinen Vorteil dadurch, dass der Parameter eine rvalue Referenz eigentlich ist.
Sorry an den TE dass ich das hier ein bisschen kapere, aber das klingt nun doch ziemlich interessant. Hast du irgendwas dazu, dass aus der eigentlichen std::string(void)-Funktion eine std::string&&(void)-Funktion wird?
Ich vermute du spielst auf RVO an, stimmt das? Und wenn ja, ist irgendwo garantiert wie das funktioniert?

Weil für mich klingt das jetzt nicht so 100% logisch und standardkonform, ich finde dazu aber auch in Google nichts, und wenn du offenbar weißt wovon du sprichst, teilst du es sicher gerne :)

Padmak
10/11/2015 02:28 MrSm!th#18
Quote:
Mach dir nicht so viel Gedanken über diesen einen String, man wird kaum einen Unterschied merken.
Ich muss dich korrigieren: Man wird keinen Unterschied bemerken.

Diese Art die Optimierung ist einfach nicht so viele Gedanken wert. Es geht hier nicht um einen Webserver oder etwas in der Art, der täglich eine riesige Menge von langen Strings in wenigen Millisekunden verarbeiten muss.

"Premature optimization is the root of all evil."
10/11/2015 11:36 th0rex#19
Quote:
Originally Posted by Padmak View Post
Sorry an den TE dass ich das hier ein bisschen kapere, aber das klingt nun doch ziemlich interessant. Hast du irgendwas dazu, dass aus der eigentlichen std::string(void)-Funktion eine std::string&&(void)-Funktion wird?
Ich glaube da habe ich mich falsch ausgedrückt. An der Funktionssignatur wird nichts verändert.

Quote:
Originally Posted by Padmak View Post
Ich vermute du spielst auf RVO an, stimmt das? Und wenn ja, ist irgendwo garantiert wie das funktioniert?
Nein tue ich nicht. RVO findet innerhalb der Funktion statt (dh. in der Funktion die etwas zurück gibt). Ja es ist garantiert wie und wann das funktioniert.

Also. Grundsätzlich ist eine rvalue Referenz auch eine Referenz. Das heißt, dass sowas:
Code:
MyClass&& get()
{
    MyClass m;
    return std::move(m);
}
eine Referenz auf ein nicht mehr existierendes Objekt (m) zurück gibt (undefined behaviour). Deswegen wird der Compiler die Signatur auch nicht zu std::string&& get() ändern und man selber sollte es auch nicht (außer man weiß wirklich was man macht; die stl macht das bei dem operator* vom iterator z.B.). Dafür ist ja schließlich RVO/NRVO da.
Code:
std::string getMyVal()
{
     std::string ret = "......";
     return ret; // HIER findet NRVO statt, da ret nicht mehr genutzt wird darf der compiler das.
}
Aber RVO/NRVO hat nicht wirklich was, mit dem was ich gesagt habe zu tun. Es kann halt nur in der Funktion, die etwas zurück gibt, statt finden, aber mir ging es eher darum, welche Funktion aufgerufen wird, also um Overload Resolution.

Ich habe mich da definitiv falsch ausgedrückt. Der Typ von dem Rückgabewert ist und bleibt MyClass bzw. std::string.
Code:
MyClass getMyClass(){...}
void myFunc(const MyClass& m){...} // 1
void myFunc(MyClass&& m){...}//2

myFunc(getMyClass()); // 3
Bei Zeile 3 muss jetzt zuerst getMyClass() aufgerufen werden. Dann hat der Compiler da dieses Objekt vom Typ MyClass rumliegen und das ist defintiv temporär. RValue (=temporäre) Objekte können an lvalue und rvalue Referenzen gebunden werden, aber eine rvalue Referenz ist die bessere Übereinstimmung. Das heißt, wenn der Compiler jetzt die Funktion sucht, die aufgerufen werden soll, hätte man mit der 2. Funktionssignatur die bessere Übereinstimmung. Wenn die 2. Funktionsignatur nicht existiert, weil der Programmierer sie nicht geschrieben hat, dann wird die 1. Funktion aufgerufen.