2016-02-02 3 views
1

Сначала я создаю массив unique_ptr объектов Foo. И затем я перемещаю объекты в вектор, как показано в приведенном ниже коде. Но этот код не компилируется. Другой вопрос, так как объекты были выделены с использованием версии массива нового оператора. Что произойдет, если возникло исключение, и программа должна завершиться раньше, чем я вернусь к объекту в массив unique_ptr? В такой ситуации вектор vec уничтожит его содержимое, используя оператор delete, а не версию массива оператора delete? Как мы решаем эту проблему?Перемещение объектов из массива unique_ptr в вектор

class Foo 
{ 
public: 
    int id; 

    Foo(){}; 
}; 

int main() 
{ 
    int n = 10; 

    std::unique_ptr<Foo []> fooarr(new Foo[n]); 

    std::vector<std::unique_ptr<Foo>> vec; 

    for(int i=0 ; i<n ; i++){ 
    fooarr[i].id = i; 
    } 

    for(int i=0 ; i<n ; i++){ 
    vec.push_back(std::move(fooarr[i])); 
    } 

    //then move back the Foo objects from vec to fooarr 

} 

Вот что я получил от компилятора.

main.cpp: In function 'int main()': main.cpp:47: error: no matching function for call to 'std::vector >, std::allocator > > >::push_back(Foo)' /usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/bits/stl_vector.h:733: note: candidates are: void std::vector<_Tp, _Alloc>::push_back(const _Tp&) [with _Tp = std::unique_ptr >, _Alloc = std::allocator > >] /usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/bits/stl_vector.h:746: note: void std::vector<_Tp, _Alloc>::push_back(_Tp&&) [with _Tp = std::unique_ptr >, _Alloc = std::allocator > >]

+0

@TartanLlama Первое состоит в том, что я не понимаю, ошибка , Вы? –

+0

@ PeterA.Schneider Это означает, что вы не можете 'push_back'' Foo', когда ожидается 'std :: unique_ptr '. – TartanLlama

+0

@TartanLlama после правильного уделения внимания дракделированию, после вашего другого комментария, ошибка произвела полный смысл ;-). –

ответ

1

Если вы хотите std::vector<std::unique_ptr<Foo>>, то вам необходимо динамически выделять новый Foo для каждого элемента массива:

for(int i=0 ; i<n ; i++){ 
    vec.push_back(std::make_unique<Foo>(std::move(fooarr[i]))); 
} 
+0

Почему? Он мог также переместить один уникальный_ptr в каждый элемент, что он пытается сделать, или он не мог? Если нет, почему бы и нет? –

+0

@ PeterA.Schneider Исходная структура - это 'std :: unique_ptr' для одного блока' Foo ', выделенного с помощью' new [] 'и освобожденного' delete [] '. Структура OP хочет изменить на - это коллекция 'N'' std :: unique_ptr '' 'Foo' s. Это совершенно разные вещи. – TartanLlama

+0

Ах! Да, теперь я вижу это, спасибо. Считаете ли вы, что непонимание (т. Е. Ошибочное определение Foo) - проблема OP? («Я создал массив unique_ptr объектов Foo» - почему кто-нибудь это сделал? :-) –