2016-12-09 8 views
4

У меня есть класс, который выглядит следующим образом:странно ошибка: использование удаленной функции «станд :: unique_ptr <_Tp, _Dp> :: unique_ptr когда нет указателей на самом деле не создали

template<typename T> 
    using VectorPtr=std::vector<std::unique_ptr<T>>; 

    template<typename T> 
    using VectorRawPtr=std::vector<T*>; 

    class ItemsSet{ // <-- Compiler say this line contans an error 0_o ? 
    public: 
      ItemsSet(VectorPtr<Item>& items); 

      ~ItemsSet() = default; 

      VectorRawPtr<Item> GetItems(); 

      VectorRawPtr<Item> GetSuitableItemsForPeriod(const IPeriod &period); 

      double CalculateTotal(); 
    private: 
     VectorPtr<Item> _items; 
    }; 

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

ItemsSet::ItemsSet(VectorPtr<Item> & items) { 
    for(auto &itm: items){ 
     _items.emplace_back(std::move(itm)); 
    } 
} 

однако этот код не компилируется и не с ошибкой:

/usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/bits/stl_construct.h: In instantiation of 'void std::_Construct(_T1*, _Args&& ...) [with _T1 = std::unique_ptr<Item, std::default_delete<Item> >; _Args = {const std::unique_ptr<Item, std::default_delete<Item> >&}]': 
/usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/bits/stl_uninitialized.h:75:18: required from 'static _ForwardIterator std::__uninitialized_copy<_TrivialValueTypes>::__uninit_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = __gnu_cxx::__normal_iterator<const std::unique_ptr<Item, std::default_delete<Item> >*, std::vector<std::unique_ptr<Item, std::default_delete<Item> >, std::allocator<std::unique_ptr<Item, std::default_delete<Item> > > > >; _ForwardIterator = std::unique_ptr<Item, std::default_delete<Item> >*; bool _TrivialValueTypes = false]' 
/usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/bits/stl_uninitialized.h:126:15: required from '_ForwardIterator std::uninitialized_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = __gnu_cxx::__normal_iterator<const std::unique_ptr<Item, std::default_delete<Item> >*, std::vector<std::unique_ptr<Item, std::default_delete<Item> >, std::allocator<std::unique_ptr<Item, std::default_delete<Item> > > > >; _ForwardIterator = std::unique_ptr<Item, std::default_delete<Item> >*]' 
/usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/bits/stl_uninitialized.h:281:37: required from '_ForwardIterator std::__uninitialized_copy_a(_InputIterator, _InputIterator, _ForwardIterator, std::allocator<_Tp>&) [with _InputIterator = __gnu_cxx::__normal_iterator<const std::unique_ptr<Item, std::default_delete<Item> >*, std::vector<std::unique_ptr<Item, std::default_delete<Item> >, std::allocator<std::unique_ptr<Item, std::default_delete<Item> > > > >; _ForwardIterator = std::unique_ptr<Item, std::default_delete<Item> >*; _Tp = std::unique_ptr<Item, std::default_delete<Item> >]' 
/usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/bits/stl_vector.h:322:31: required from 'std::vector<_Tp, _Alloc>::vector(const std::vector<_Tp, _Alloc>&) [with _Tp = std::unique_ptr<Item, std::default_delete<Item> >; _Alloc = std::allocator<std::unique_ptr<Item, std::default_delete<Item> > >]' 
/cygdrive/d/code/itemSet.h:4:19: required from here 
/usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/bits/stl_construct.h:75:7: error: use of deleted function 'std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = Item; _Dp = std::default_delete<Item>]' 
    { ::new(static_cast<void*>(__p)) _T1(std::forward<_Args>(__args)...); } 

Может кто-нибудь объяснить мне, что Я делаю неправильно и как я могу исправить свою проблему?

+0

Возможно, ошибка вызвана 'GetItems()'? Он не возвращает ссылку, поэтому скопировал бы вектор (который, в свою очередь, попытался бы скопировать все 'unique_ptr' внутри него). 'GetSuitableItemsForPeriod()' может иметь такую ​​же проблему. На основе кода, который вы опубликовали, кажется, что этот класс будет работать лучше с 'shared_ptr', а не' unique_ptr'. – Andy

+0

@ Andy Я обновил вопрос и изменил эти методы, чтобы возвращать исходные указатели, но ошибка все еще существует. –

+0

Возвращение исходных указателей кажется очень опасным - это именно та ситуация, для которой предназначен 'shared_ptr'. Только другое, о чем я могу думать, это как-то связанное с инициализацией '_items'. Вы можете попробовать переместить аргумент конструктора непосредственно в '_items', как это было предложено в ответе. – Andy

ответ

6

Я уверен, что актуальной проблемой является неявный экземпляр конструктора ither для ItemsSet или Item. Поскольку вы используете unique_ptr, который не может быть действительно скопирован, конструктор копирования не может быть сгенерирован должным образом. Попробуйте явно удалить конструкторы копирования и найти место, где они использовались, и изменить это место для перемещения объявления, например, или использовать общие указатели.

+0

Спасибо, да, я попытался скопировать ItemSet в несколько мест. Когда я их заменил на ItemSet, ошибка исчезла. –

+0

Удивленный вопрос имеет значение, пока вы на самом деле не попытаетесь скопировать 'ItemsSet'. Это не показано здесь. –

1

Это не тот код, который вызывает ошибку (номера строк не совпадают, а также ошибки, вы должны представить здесь реальный тестовый файл), но мы все еще можем увидеть проблему.

unique_ptr s не могут быть скопированы (они уникальны!), Но путем копирования-инициализации _items из всего их вектора вы пытаетесь скопировать их все. Вы не можете этого сделать.

Вы можете переместить аргумент конструктора в _items.

+0

change 'ItemsSet (VectorPtr items)' to 'ItemsSet (VectorPtr & items)' не решает проблему. –

+0

@silent_coder: проблема заключается в определении этого конструктора (в частности, списка инициализации члена). Ваш вопрос неполный. –

+0

Я добавил код конструктора к вопросу, но компилятор говорит, что он не работает в файле заголовка, а не в одном из них. Я понимаю, что копирование не разрешено для unique_ptr, и я не копирую их. –

0

Я не знаю, будет ли это исправить или нет, но вы можете попробовать переместить параметр конструктора непосредственно в _items вместо перемещения каждого отдельного элемента в него:

ItemsSet::ItemsSet(VectorPtr<Item>&& items) 
: _items(std::move(items)) 
{ 
} 
+0

К сожалению, я не думаю, что у этого есть повод для работы лучше. – Quentin

+0

Да, это не исправление проблемы = (Я подействовал так же, как я понял, этот код в файле cpp. –

 Смежные вопросы

  • Нет связанных вопросов^_^