Default move constructor



  • Hallo zusammen,

    nur eine kurze Nachfrage. Ist der automatisch erzeugte move constructor immer ein move auf allen membern einer Klasse?

    Hierzu folgendes kurzes Beispiel:

    #include <iostream>
    class Foo{
    public:
            Foo(){}
            Foo(Foo&& f){
                    std::cout << "move" << std::endl;
            }
            Foo(const Foo& f){
                    std::cout << "copy" << std::endl;
            }
    };
    
    class Bar{
            Foo foo;
    };
    
    Bar create_bar(){
            Bar bar;
            return bar;
    }
    
    Foo create_foo(){
            Foo foo;
            return foo;
    }
    
    int main(){
            Bar bar = std::move(create_bar()); // std::move, da sonst move/copy wegoptimert?
            Foo foo = std::move(create_foo());
    }
    

    move
    move

    Gruß,
    XSpille



  • Deine moves hier sind unnötig - der Returnwert einer Funktion ist immer ein RValue, wenn er keine Referenz ist. Daher wird hier automatisch der Move-Konstruktor aufgerufen. Der default-Move Ctor moved immer alle Member, richtig.



  • 314159265358979 schrieb:

    Deine moves hier sind unnötig - der Returnwert einer Funktion ist immer ein RValue, wenn er keine Referenz ist. Daher wird hier automatisch der Move-Konstruktor aufgerufen. Der default-Move Ctor moved immer alle Member, richtig.

    thx.

    Siehe Kommentar, warum ich da ein std::move habe 😉

    Bar bar = std::move(create_bar()); // std::move, da sonst move/copy wegoptimert?
    

    EDIT: Zumindest habe ich ohne std::move keine Ausgabe 😉



  • XSpille schrieb:

    EDIT: Zumindest habe ich ohne std::move keine Ausgabe 😉

    Das liegt daran, dass der Compiler den return-Value der Funktionen wegoptimiert, d.h. es gibt keinen RValue mehr, der noch zu moven wäre.



  • pumuckl schrieb:

    XSpille schrieb:

    EDIT: Zumindest habe ich ohne std::move keine Ausgabe 😉

    Das liegt daran, dass der Compiler den return-Value der Funktionen wegoptimiert, d.h. es gibt keinen RValue mehr, der noch zu moven wäre.

    Danke für die Bestätigung, genau davon bin ich ausgegangen, war mir allerdings nicht 100%ig sicher.



  • Man sollte dabei auch darauf achten, dass einige Compiler (z.B. VC10) gar keinen default-Move Ctor erzeugen.

    gruss
    dirk



  • dbu schrieb:

    Man sollte dabei auch darauf achten, dass einige Compiler (z.B. VC10) gar keinen default-Move Ctor erzeugen.

    gruss
    dirk

    Genau deswegen fragte ich... Sollten sie denn eigentlich einen erzeugen?



  • @XSpille:
    Wenn ich die Regeln richtig im Kopf habe (ich hoffe ich habe)...:

    Wenn du selbst keinen Copy/Move-Ctor, keinen Copy/Move Assignment-Operator und keinen Dtor definierst (also keinen der "grossen 5" *g*) dann sollte der Compiler alle 5 implizit definieren.

    Sobald du eins davon selbst definierst, sollte der Compiler die restlichen NICHT mehr implizit definieren.

    MSVC 10 setzt das allerdings nicht um, der setzt immer noch die C++03 Regeln um. D.h. er tut auch nie einen Move-Ctor oder Move-Assignment-Operator implizit definieren.



  • hustbaer schrieb:

    @XSpille:
    Wenn ich die Regeln richtig im Kopf habe (ich hoffe ich habe)...:

    Wenn du selbst keinen Copy/Move-Ctor, keinen Copy/Move Assignment-Operator und keinen Dtor definierst (also keinen der "grossen 5" *g*) dann sollte der Compiler alle 5 implizit definieren.

    Sobald du eins davon selbst definierst, sollte der Compiler die restlichen NICHT mehr implizit definieren.

    MSVC 10 setzt das allerdings nicht um, der setzt immer noch die C++03 Regeln um. D.h. er tut auch nie einen Move-Ctor oder Move-Assignment-Operator implizit definieren.

    thx 👍


Log in to reply