2016-09-13 7 views
0

Предположим, у меня есть объект, который содержит некоторые данные:Правильный тип параметра для перемещения объекта в вектор

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

И структуру, которая содержит некоторые объекты:

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

телефонный код хочет построить объект и добавьте его в держатель без создания копий, поскольку объект может содержать миллионы элементов. Моя первая мысль была, чтобы грифели движения:

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

Однако другие программисты могут не знать, что объект он передается Держателю :: AddObject оставит его в неопределенном состоянии и продолжает работать над ней. Таким образом, я оставляю его в вызывающий код явно переместить объект в копию, иначе копия строится:

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

телефонный код затем выглядит следующим образом:

Holder h; 
Object o; 
// populate c 

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

Является ли использование станд :: Переместить в этом контексте правильно? Есть ли альтернативный, более правильный и очевидный способ справиться с этим?

+0

Make 'Object' подвижны, но не копируемые и компилятор сообщит вам, если вы делаете что-то неправильно – Slava

ответ

3

Вы можете разместить конструкцию своих объектов в векторе держателя. Это также позволяет передавать значение r (которое можно перенести).

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

std::forward пересылает значение категории параметров, то есть, если вы назвали вашу функцию с RValue, то std::vector:: emplace_back() будет также получить RValue.

Таким образом, h.emplaceObject(std::move(o)) будет вызывать конструктор перемещения Object один раз.

Btw, это называется perfect forwarding.