verständnisproblem std::move / move-konstruktor



  • hallo,

    im folgenden snippet:

    #include <utility>
    
    struct A{};
    struct B
    {
    	A a;
    	A const& get_a() const & noexcept { return a; }
    	A& get_a() & noexcept { return a; }
    	A&& get_a() && noexcept { return std::move( a ); }
    
    	B() noexcept = default;
    
    	// Variante 1
    	B(B&& rhs)
    		: a( std::move( rhs.get_a() ) )
    	{}
    
    	// Variante 2
    	B(B&& rhs)
    		: a( std::move( rhs ).get_a() )
    	{}
    };
    
    int main()
    {
        B a, b{ std::move( a ) };
    }
    

    welche der beiden varianten der move-konstruktor-implementationen ist idiomatischer? mir ist bewusst, dass die explizite definition hier unnötigt ist; das ist nur ein beispiel.

    ausserdem: wenn ich B&& rhs als funktionsparameter stehen habe, was ist dann der typ von rhs ? wenn er B&& wäre, dann gäbe es doch keinen grund, std::move zu benutzen, oder?

    LG



  • move your booty schrieb:

    welche der beiden varianten der move-konstruktor-implementationen ist idiomatischer?

    Idiomatischer? Was auch immer das heißen mag:

    B(B&& rhs)
            : a( std::move( rhs.a ) )
        {}
    

    move your booty schrieb:

    ausserdem: wenn ich B&& rhs als funktionsparameter stehen habe, was ist dann der typ von rhs ?

    Wenn es einen Namen hat ist es keine rvalue Referenz.


  • Mod

    move your booty schrieb:

    ausserdem: wenn ich B&& rhs als funktionsparameter stehen habe, was ist dann der typ von rhs ?

    Der Typ der Entität namens rhs ist B&& , und das ist auch, was decltype(rhs) dir geben wird. Allerdings ist der Ausdruck rhs ein lvalue vom Typ B (was decltype((rhs)) dir bestätigt, weil es B& sein wird). Was das heißt, ist, dass von dem Ausdruck rhs nicht gemoved wird. Du musst den Namen schon zu einem rvalue casten (was move idiomatisch für dich erledigt).


Log in to reply