代码之家  ›  专栏  ›  技术社区  ›  silent_coder

奇怪错误:当没有真正创建指针时,使用已删除函数“std::unique_ptr<_Tp,_Dp>::unique_ ptr

  •  15
  • silent_coder  · 技术社区  · 9 年前

    我有一个类,看起来像这样:

        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)...); }
    

    3 回复  |  直到 9 年前
        1
  •  18
  •   Ph0en1x    9 年前

    我很确定实际的问题是它的隐式复制构造函数 ItemsSet Item .因为你在使用 unique_ptr 它不能真正复制,复制构造函数不能正确生成。尝试显式删除复制构造函数并找到它们使用的位置,并更改这些位置以移动声明,例如,或使用共享指针。

        2
  •  3
  •   Lightness Races in Orbit    9 年前

    这不是产生错误的实际代码(行号不匹配,错误也不匹配;您应该在这里提供一个实际的测试用例),但我们仍然可以看到问题。

    unique_ptr s无法复制(它们是“唯一的”!),然而,通过复制初始化 _items 从它们的整个向量中,你试图复制它们。你不能那样做。

    你可以 移动 构造函数参数为 _项目 相反

        3
  •  0
  •   Andy    9 年前

    我不知道这是否会修复它,但您可以尝试将构造函数参数直接移动到 _items 而不是将每个单独的构件移动到其中:

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