Wird der Move-Ctor nu default-generiert oder nicht?



  • Ich bin grade ei wenig stutzig geworden, als ich feststellen musste, dass ein von mir angenommener generierter Move-Ctro nicht zu existieren schien:

    #include <utility>
      class nc
      {
       protected:
          nc() {}
          ~nc() {}
       private:  
          nc( const nc& ); //verhindert nc(nc&&)
          const nc& operator=( const nc& );
      };
    
    struct Base : nc //oder boost::noncopyable, ist das Selbe
    {
      Base(Base&&) {} //wird wegen fehlendem nc(nc&&) nicht generiert
      Base() {}       //wird wegen Base(Base&&) nicht generiert
    };
    
    struct Derived : Base
    {
      //hier sollte hier generiert werden!
    };
    
    int main()
    {
       Derived d1;
       Derived d2(std::move(d1));
    }
    

    Sowohl gcc-4.5.1 als auch MSVC2010 spucken hier Zähne, weil sie den COPY-Ctor nicht erstellen können (wegen privatem nc(nc const&))
    Dabe wird hier doch garnichts kopiert sondern gemoved?



  • Nächstes Verständnisproblem:

    #include <utility>
      class noncopyable
      {
       protected:
          noncopyable() {}
          ~noncopyable() {}
       private:  // emphasize the following members are private
          noncopyable( const noncopyable& );
          const noncopyable& operator=( const noncopyable& );
      };
    
    struct Base : noncopyable
    {
      Base() = default;
      Base(Base&&) {}
    };
    
    struct Derived : Base
    {
      Derived() = default;
      Derived(Derived&&) {}
    };
    
    int main()
    {
       Derived d1;
       Derived d2(d1);
    }
    

    Hier darf meines Wissens kein copy-ctor generiert werden, weil sowohl Base als auch Derived Move-Ctoren definiert haben. Dennoch macht GCC erst bei nc(nc const&) die grätsche, versucht also lustig sowohl für Base als auch für Derived den Copy-Ctor zu generieren.


  • Mod

    GCC 4.6 schluckt das ohne Mucken. edit: Das bezieht sich auf den ersten Beitrag, du warst schneller als ich.

    edit2: Dafür schluckt GCC 4.6 den zweiten Code wiederum nicht. Und sagt (meiner Meinung nach) richtigerweise:

    In function ‘int main()’:
    29:17: error: cannot bind ‘Derived’ lvalue to ‘Derived&&’
    22:3: error:   initializing argument 1 of ‘Derived::Derived(Derived&&)’
    

    Oder meintest du hier was anderes?



  • SeppJ schrieb:

    GCC 4.6 schluckt das ohne Mucken. edit: Das bezieht sich auf den ersten Beitrag, du warst schneller als ich.

    edit2: Dafür schluckt GCC 4.6 den zweiten Code wiederum nicht.

    Genau so sollte es sein. Aber MSVC enttäuscht mich leider immer weiter was C++11 angeht 😞



  • Siehe http://wiki.apache.org/stdcxx/C%2B%2B0xCompilerSupport. GCC 4.6 kann RValue Refenzen V3.0, während MSVC nur 2.1 kann.



  • Wow, Clang hat ja wirklich GCC überholt, obwohl es vor Kurzem noch fast nichts im Bezug auf C++11 gab. Scheint echt produktiv zu sein, einen Compiler von Grundauf neu zu schreiben, haben ja in Windeseile komplett C++03 und jetzt auch C++11 implementiert, was die ganzen Dinosaurier nicht schaffen.


Anmelden zum Antworten