seltsamer Fehler: use of deleted function 'std::unique_ptr<_Tp, _Dp>::unique_ptr, wenn kein Zeiger wirklich geschaffen
Habe ich eine Klasse, die so aussieht:
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;
};
Konstruktor sieht wie folgt aus:
ItemsSet::ItemsSet(VectorPtr<Item> & items) {
for(auto &itm: items){
_items.emplace_back(std::move(itm));
}
}
allerdings dieser code nicht kompiliert und ist fehlgeschlagen mit dem Fehler:
/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)...); }
Könnte jemand mir erklären was ich falsch mache und wie könnte ich das beheben mein problem?
- Vielleicht ist der Fehler durch
GetItems()
? Es ist nicht wieder eine Referenz, so, die Kopie der Vektor (die wiederum versuchen, Sie zu kopieren alleunique_ptr
s in es).GetSuitableItemsForPeriod()
vielleicht das gleiche problem haben wie gut. Basierend auf dem code, den Sie geschrieben, wie es scheint, diese Klasse würde besser funktionieren mitshared_ptr
stattunique_ptr
. - Ich aktualisierte Frage, und ändern Sie die Methoden für die Rückgabe von raw-Pointern, aber Fehler immer noch da.
- Rückkehr raw-Zeiger scheint sehr gefährlich - das ist genau die Art von situation
shared_ptr
ausgelegt ist. Nur andere Sache, die ich denken kann ist, es hat etwas zu tun mit der Initialisierung der_items
. Sie könnten versuchen, das argument des Konstruktors direkt in_items
wie bereits in der Antwort. - ändern Konstruktor ItemsSet(VectorPtr<Item>&& items) und bewegliche Elemente innen haben keine Wirkung
- Das ist nicht das, was ich meinte - die werde ich hinzufügen, eine Antwort leichter, es zu erklären gibt.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich bin mir ziemlich sicher, dass eigentliche problem ist ein impliziter copy-Konstruktor ither für
ItemsSet
oderItem
. Weil Sie mitunique_ptr
's, die nicht wirklich kopiert, copy-Konstruktor nicht erzeugt werden, ordnungsgemäß. Versuchen Sie explizit löschen, copy Konstruktoren und finden Sie den Ort, wo Sie verwendet wird und ändern Sie jene Stelle zu bewegen, die Erklärung zum Beispiel, oder verwenden Sie shared Pointer.ItemsSet
. Das ist nicht die hier gezeigt werden.Dies ist nicht der eigentliche code, der den Fehler erzeugt (Ihre Linie zahlen nicht übereinstimmen, und auch nicht die Fehler; Sie muss einen tatsächlichen testcase hier), aber wir können immer noch das problem.
unique_ptr
s kann nicht kopiert werden (Sie sind "einzigartig"!), noch durch copy-Initialisierung_items
aus einem ganzen Vektor von Ihnen, Sie versuchen, Sie zu kopieren alle. Das kannst du nicht tun.Könnte man bewegen das Konstruktor-argument in
_items
statt.ItemsSet(VectorPtr<Item> items)
zuItemsSet(VectorPtr<Item>& items)
nicht die Lösung des Problems.Ich weiß nicht, ob dieser fix wird oder nicht, aber Sie könnten versuchen, die parameter des Konstruktors direkt in
_items
anstatt sich jedes einzelne Mitglied in den it: