Anwendung von PerfectForwarding in der Praxis



  • Hallo zusammen,

    ich habe in meiner Anwendung viele Stellen, an denen z.B. ein std::vector erstellt und befüllt wird. Danach wird dieser Vector an eine andere Klasse zur weiterverarbeitung überreicht.

    Die aufrufende Klasse macht mit dem std::vector danach nichts mehr. Das hört sich für mich nach einem Fall an, wo ich die Move-Semantik verwenden könnte um ohne SmartPtr/Heap-Objekte billig Objekte weiterreichen könnte.

    Nur so richtig klar ist mir nicht, wie der Code aussehen sollte.

    Macht man das wie folgt dargestellt?

    class Datensenke {
      public:
      Datensenke(std::vector<size_t> &&vec)
        : myVec_(vec) {
      }
    
      void machWas();
    
      private:
      std::vector<size_t> myVec_;
    };
    
    class Datenquelle {
      public:
      void verarbeite() {
          for (size_t i = 0; i < 100; ++i) {
              myVec_.push_back(i);
          }
    
          Datensenke senke(std::move(myVec_));
          senke.machWas();
      }
    
      private:
      std::vector<size_t> myVec_;
    };
    

    Falls ja, eine Folgefrage: wie kann ich eine RValue-Referenz weitergeben? Beispiel:

    class Datensenke {
      public:
      Datensenke(std::vector<size_t> &&vec)
        : myVec_(vec) {
      }
    
      void machWas();
    
      private:
      std::vector<size_t> myVec_;
    };
    
    void verarbeite(std::vector<size_t> &&vec)  // <<---- Ist das so richtig, oder sollte hier std::vector<size_t> stehen?
    {
          Datensenke senke(std::move(myVec_));  // <<---- Wie gebe ich hier vec weiter?
          senke.machWas();
    }
    
    int main()
    {
        std::vector<size_t> myVec;
        for(size_t i = 0; i < 1000; ++i) {
           myVec.push_back(i);
        }
    
       verarbeite(std::move(myVec));
    
       return 0;
    }
    

    Danke.

    Grüße Wadim


  • Mod

    Datensenke(std::vector<size_t> &&vec) 
        : myVec_(vec) { 
      }
    

    vec ist ein lvalue. Daher wird eine Kopie durchgeführt. std::move(vec) ist hingegen ein rvalue (xvalue).



  • Arcoth schrieb:

    Datensenke(std::vector<size_t> &&vec) 
        : myVec_(vec) { 
      }
    

    vec ist ein lvalue. Daher wird eine Kopie durchgeführt. std::move(vec) ist hingegen ein rvalue (xvalue).

    Interessant, ich bekomme bei meinem g++ keine Warnung an dieser Stelle.

    Was für ein Konstruktor ruft der g++ dann auf (ohne das move)?



  • P.S. was ist der Unterschied zwischen std::move und std::forward?


Anmelden zum Antworten