2016-09-13 1 views
0

Angenommen bewegt Ich habe ein Objekt, das einige Daten enthält:korrekter Parametertyp für das Objekt in dem Vektor

struct Object 
{ 
    std::vector<float> data; 
} 

und eine Struktur, die einige Objekte enthält:

struct Holder 
{ 
    private: 
    std::vector<Object> objects_; 
} 

Telefonvorwahl will ein Objekt bauen und fügen Sie es einem Holder hinzu, ohne Kopien zu erstellen, da das Objekt Millionen von Elementen enthalten kann. Mein erster Gedanke war, lassen Halter den Umzug Griff:

struct Holder 
{ 
    void addObject(Object& object) 
    { 
     objects_.push_back(std::move(object)); 
    } 
    private: 
    std::vector<Object> objects_; 
} 

jedoch andere Programmierer nicht darüber im Klaren sein, dass das Objekt, um es Halter übergeben :: addObject es in einem nicht spezifizierten Zustand verlassen wird und weiter daran arbeiten. So lasse ich es Code Aufruf explizit das Objekt in einer Kopie zu bewegen, sonst eine Kopie aufgebaut ist:

struct Holder 
{ 
    void addObject(Object object) 
    { 
     objects_.push_back(std::move(object)); 
    } 
    private: 
    std::vector<Object> objects_; 
} 

Telefonvorwahl dann wie folgt aussieht:

Holder h; 
Object o; 
// populate c 

h.addObject(std::move(o)) 

Ist der Einsatz von std :: in diesem Zusammenhang richtig bewegen? Gibt es eine alternative, korrektere und offenere Art, damit umzugehen?

+0

Fabrikat 'Object' beweglich, aber nicht kopierbar und Compiler wird Ihnen sagen, wenn Sie etwas falsch machen – Slava

Antwort

3

Sie könnten die Konstruktion Ihrer Objekte in den Vektor des Halters einfügen. Dies ermöglicht auch das Übergeben eines R-Werts (der verschoben werden kann).

template<typename... Args> 
void emplaceObject (Args... && args) { 
    objects_.emplace_back(std::forward<Args>(args)...); 
} 

std::forward leitet die Wertkategorie der Parameter, das heißt, wenn Sie Ihre Funktion mit einem R-Wert genannt, dann die std::vector:: emplace_back() wird auch ein R-Wert bekommen.

So h.emplaceObject(std::move(o)) würde einmal den Move-Konstruktor von Object aufrufen.

Btw, das nennt man perfect forwarding.

Verwandte Themen