Automatisches generieren von Konstruktoren



  • Hallo @all

    Ich habe folgendes Problem mit der Generierung von Konstruktoren vom Compiler:

    class A
    {
    public:
    	A()
    	{
    		a = "Hallo";
    		b = " ";
    		c = "Welt";
    	}
    
    	A( const A& ) = default;
    	A( A&& ) = default;
    
    	string a,b,c;
    };
    

    mit dem Schlüsselwort default, soll es dem Compiler möglich sein, einfache Kopier-Konstruktoren oder Move-Konstruktoren zu bauen. Beim Copy-Ctor funktioniert die Sache auch ziemlich gut, jedoch meckert er beim Move-Ctor rum.
    Fehlermeldung:

    'A::A(A &&)' : is not a special member function which can be defaulted

    Ist es demnach nur möglich Kopier-Konstruktoren automatisch erstellen zu lassen?

    Dies ist ein vereinfachtes Beispiel um mein Problem zu verdeutlichen.

    Ich habe außerdem noch eine zweite "kleine" Frage:
    Wenn ich Parameter als rvalue übergeben möchte, habe ich das bisher immer so gemacht:

    void f( string&& str )
    {
    	mystr = std::forward<string>( str );
    }
    

    Ich habe letzens eine 2. Version gesehen:

    void f( string str )
    {
        mystr = std::move( str );
    }
    

    Ich persönlich finde die obere Variante besser (und auch richtiger) aber vllt übersehe ich etwas, weshalb die zweite Variante doch besser sein könnte.

    Danke und MfG

    Hlymur



  • std::forward vs std::move:

    Siehe mal folgendes Beispiel:

    template <typename T>
    void func(T&& param) {
        otherFunc(std::forward<T>(param));
    }
    

    Durch type deduction und reference collapsing kann T&& hier T&& (wenn ein rvalue übergeben wurde) und T const& (wenn ein lvalue übergeben wurde) sein.
    std::move würde nun beides egal was es ist zu einer rvalue-ref casten. std::forward macht das nicht, es leitet genau das weiter (lvalue / rvalue).
    In einem nicht template Kontext ist std::forward also (meines wissens) fehl am Platz.



  • Wenn der Compiler VS2013 ist, kann er Movekonstruktoren noch nicht richtig.


  • Mod

    Durch type deduction und reference collapsing kann T&& hier T&& (wenn ein rvalue übergeben wurde) und T const& (wenn ein lvalue übergeben wurde) sein.

    .. und T& und T const&& .

    std::move würde nun beides egal was es ist zu einer rvalue-ref casten.

    Wobei angemerkt werden sollte dass T const& zu T const&& wird, was (praktisch) niemals Kandidat für Move-Konstruktoren ist.



  • Arcoth schrieb:

    Durch type deduction und reference collapsing kann T&& hier T&& (wenn ein rvalue übergeben wurde) und T const& (wenn ein lvalue übergeben wurde) sein.

    .. und T& und T const&& .

    wann denn T&?
    (Ich seh schon, ich bereu die Frage gleich und hau mir die Hand vor den Kopf... Vielleicht aber auch nicht :))


  • Mod

    5cript schrieb:

    wann denn T&?

    Das ist doch Scheißegal. Denk einfach daran, dass das eine forwarding reference ist, und Argumente mit ihr und forward exakt so weitergegeben werden wie sie ankommen. Sie const weiterzugeben, wo sie eigentlich modifizierbar sind, wäre falsch.



  • 5cript schrieb:

    Arcoth schrieb:

    Durch type deduction und reference collapsing kann T&& hier T&& (wenn ein rvalue übergeben wurde) und T const& (wenn ein lvalue übergeben wurde) sein.

    .. und T& und T const&& .

    wann denn T&?

    Na, immer wenn ein nicht konstantes LValue übergeben wird.
    http://ideone.com/C8lfkC



  • Also zum Thema Move-Ctor:
    Mit VS 2013 geht es nicht, aber grundsätzlich schon? ok, dann hoffe ich auf VS 2015 oder GCC

    Zum zweiten Theme:
    Wenn ich nun einfach z.B. einen String verschieben möchte.
    Dann als Parameter std::string oder std::string&&, aber aufjedenfall kein std::forward sondern std::move?

    void func(std::string oder std::string&& str)
    {
        mystr = std::move(str);
    }
    

Anmelden zum Antworten