Non-copyable elements in a std::vector of std::lists












1














I have a non-copyable class, simplified as follows:



struct NonCopyable
{
NonCopyable() = default;
NonCopyable(const NonCopyable&) = delete;
NonCopyable& operator = (const NonCopyable&) = delete;
NonCopyable(NonCopyable&&) = default;
NonCopyable& operator = (NonCopyable&&) = default;
};


I store the objects of this class in various std::lists. At one point I have an empty std::vector of these lists, which I would like to resize to contain a fixed number of empty lists. However, this complains about the lack of a NonCopyable copy constructor, even though (as far as I can see) it shouldn't be trying to construct any NonCopyables!



std::vector<std::list<NonCopyable>> v; // OK
v.resize(4); // ERROR
v.emplace_back(); // ERROR
std::list<NonCopyable> l; // OK
v.push_back(l); // ERROR (unsurprisingly)
v.push_back(std::move(l)); // ERROR


Why is this? Is there any way to do this without making the class copyable?



I'm using VS2017 with /std:c++17 in case that makes any difference.





Here's the full error output from just trying to resize (first two lines above).



1>------ Build started: Project: testcore, Configuration: Debug x64 ------
1>testcard.cpp
1>c:program files (x86)microsoft visual studio2017communityvctoolsmsvc14.15.26726includexmemory0(881): error C2280: 'NonCopyable::NonCopyable(const NonCopyable &)': attempting to reference a deleted function
1>[...]testcard.cpp(30): note: see declaration of 'NonCopyable::NonCopyable'
1>[...]testcard.cpp(30): note: 'NonCopyable::NonCopyable(const NonCopyable &)': function was explicitly deleted
1>c:program files (x86)microsoft visual studio2017communityvctoolsmsvc14.15.26726includelist(711): note: see reference to function template instantiation 'void std::_Default_allocator_traits<_Alloc>::construct<_Ty,const NonCopyable&>(_Alloc &,_Objty *const ,const NonCopyable &)' being compiled
1> with
1> [
1> _Alloc=std::allocator<std::_List_node<NonCopyable,std::_Default_allocator_traits<std::allocator<NonCopyable>>::void_pointer>>,
1> _Ty=NonCopyable,
1> _Objty=NonCopyable
1> ]
1>c:program files (x86)microsoft visual studio2017communityvctoolsmsvc14.15.26726includelist(716): note: see reference to function template instantiation 'void std::_Default_allocator_traits<_Alloc>::construct<_Ty,const NonCopyable&>(_Alloc &,_Objty *const ,const NonCopyable &)' being compiled
1> with
1> [
1> _Alloc=std::allocator<std::_List_node<NonCopyable,std::_Default_allocator_traits<std::allocator<NonCopyable>>::void_pointer>>,
1> _Ty=NonCopyable,
1> _Objty=NonCopyable
1> ]
1>c:program files (x86)microsoft visual studio2017communityvctoolsmsvc14.15.26726includelist(947): note: see reference to function template instantiation 'std::_List_node<_Ty,std::_Default_allocator_traits<_Alloc>::void_pointer> *std::_List_buy<_Ty,_Alloc>::_Buynode<const NonCopyable&>(std::_List_node<_Ty,std::_Default_allocator_traits<_Alloc>::void_pointer> *,std::_List_node<_Ty,std::_Default_allocator_traits<_Alloc>::void_pointer> *,const NonCopyable &)' being compiled
1> with
1> [
1> _Ty=NonCopyable,
1> _Alloc=std::allocator<NonCopyable>
1> ]
1>c:program files (x86)microsoft visual studio2017communityvctoolsmsvc14.15.26726includelist(950): note: see reference to function template instantiation 'std::_List_node<_Ty,std::_Default_allocator_traits<_Alloc>::void_pointer> *std::_List_buy<_Ty,_Alloc>::_Buynode<const NonCopyable&>(std::_List_node<_Ty,std::_Default_allocator_traits<_Alloc>::void_pointer> *,std::_List_node<_Ty,std::_Default_allocator_traits<_Alloc>::void_pointer> *,const NonCopyable &)' being compiled
1> with
1> [
1> _Ty=NonCopyable,
1> _Alloc=std::allocator<NonCopyable>
1> ]
1>c:program files (x86)microsoft visual studio2017communityvctoolsmsvc14.15.26726includelist(1308): note: see reference to function template instantiation 'void std::list<NonCopyable,std::allocator<_Ty>>::_Insert<const NonCopyable&>(std::_List_unchecked_const_iterator<std::_List_val<std::_List_simple_types<_Ty>>,std::_Iterator_base0>,const NonCopyable &)' being compiled
1> with
1> [
1> _Ty=NonCopyable
1> ]
1>c:program files (x86)microsoft visual studio2017communityvctoolsmsvc14.15.26726includelist(1308): note: see reference to function template instantiation 'void std::list<NonCopyable,std::allocator<_Ty>>::_Insert<const NonCopyable&>(std::_List_unchecked_const_iterator<std::_List_val<std::_List_simple_types<_Ty>>,std::_Iterator_base0>,const NonCopyable &)' being compiled
1> with
1> [
1> _Ty=NonCopyable
1> ]
1>c:program files (x86)microsoft visual studio2017communityvctoolsmsvc14.15.26726includelist(1265): note: see reference to function template instantiation 'void std::list<NonCopyable,std::allocator<_Ty>>::_Insert_range<_Iter>(std::_List_unchecked_const_iterator<std::_List_val<std::_List_simple_types<_Ty>>,std::_Iterator_base0>,_Iter,_Iter,std::forward_iterator_tag)' being compiled
1> with
1> [
1> _Ty=NonCopyable,
1> _Iter=std::_List_const_iterator<std::_List_val<std::_List_simple_types<NonCopyable>>>
1> ]
1>c:program files (x86)microsoft visual studio2017communityvctoolsmsvc14.15.26726includelist(1264): note: see reference to function template instantiation 'void std::list<NonCopyable,std::allocator<_Ty>>::_Insert_range<_Iter>(std::_List_unchecked_const_iterator<std::_List_val<std::_List_simple_types<_Ty>>,std::_Iterator_base0>,_Iter,_Iter,std::forward_iterator_tag)' being compiled
1> with
1> [
1> _Ty=NonCopyable,
1> _Iter=std::_List_const_iterator<std::_List_val<std::_List_simple_types<NonCopyable>>>
1> ]
1>c:program files (x86)microsoft visual studio2017communityvctoolsmsvc14.15.26726includelist(800): note: see reference to function template instantiation 'std::_List_iterator<std::_List_val<std::_List_simple_types<_Ty>>> std::list<_Ty,std::allocator<_Ty>>::insert<std::_List_const_iterator<std::_List_val<std::_List_simple_types<_Ty>>>,void>(std::_List_const_iterator<std::_List_val<std::_List_simple_types<_Ty>>>,_Iter,_Iter)' being compiled
1> with
1> [
1> _Ty=NonCopyable,
1> _Iter=std::_List_const_iterator<std::_List_val<std::_List_simple_types<NonCopyable>>>
1> ]
1>c:program files (x86)microsoft visual studio2017communityvctoolsmsvc14.15.26726includelist(800): note: see reference to function template instantiation 'std::_List_iterator<std::_List_val<std::_List_simple_types<_Ty>>> std::list<_Ty,std::allocator<_Ty>>::insert<std::_List_const_iterator<std::_List_val<std::_List_simple_types<_Ty>>>,void>(std::_List_const_iterator<std::_List_val<std::_List_simple_types<_Ty>>>,_Iter,_Iter)' being compiled
1> with
1> [
1> _Ty=NonCopyable,
1> _Iter=std::_List_const_iterator<std::_List_val<std::_List_simple_types<NonCopyable>>>
1> ]
1>c:program files (x86)microsoft visual studio2017communityvctoolsmsvc14.15.26726includelist(796): note: while compiling class template member function 'std::list<NonCopyable,std::allocator<_Ty>>::list(const std::list<_Ty,std::allocator<_Ty>> &)'
1> with
1> [
1> _Ty=NonCopyable
1> ]
1>c:program files (x86)microsoft visual studio2017communityvctoolsmsvc14.15.26726includexmemory0(881): note: see reference to function template instantiation 'std::list<NonCopyable,std::allocator<_Ty>>::list(const std::list<_Ty,std::allocator<_Ty>> &)' being compiled
1> with
1> [
1> _Ty=NonCopyable
1> ]
1>c:program files (x86)microsoft visual studio2017communityvctoolsmsvc14.15.26726includevector(1812): note: see reference to class template instantiation 'std::list<NonCopyable,std::allocator<_Ty>>' being compiled
1> with
1> [
1> _Ty=NonCopyable
1> ]
1>c:program files (x86)microsoft visual studio2017communityvctoolsmsvc14.15.26726includevector(1811): note: while compiling class template member function 'std::list<NonCopyable,std::allocator<_Ty>> *std::vector<std::list<_Ty,std::allocator<_Ty>>,std::allocator<std::list<_Ty,std::allocator<_Ty>>>>::_Udefault(std::list<_Ty,std::allocator<_Ty>> *,const unsigned __int64)'
1> with
1> [
1> _Ty=NonCopyable
1> ]
1>c:program files (x86)microsoft visual studio2017communityvctoolsmsvc14.15.26726includevector(1479): note: see reference to function template instantiation 'std::list<NonCopyable,std::allocator<_Ty>> *std::vector<std::list<_Ty,std::allocator<_Ty>>,std::allocator<std::list<_Ty,std::allocator<_Ty>>>>::_Udefault(std::list<_Ty,std::allocator<_Ty>> *,const unsigned __int64)' being compiled
1> with
1> [
1> _Ty=NonCopyable
1> ]
1>[...]testcard.cpp(37): note: see reference to class template instantiation 'std::vector<std::list<NonCopyable,std::allocator<_Ty>>,std::allocator<std::list<_Ty,std::allocator<_Ty>>>>' being compiled
1> with
1> [
1> _Ty=NonCopyable
1> ]
1>Done building project "testcore.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 2 up-to-date, 0 skipped ==========









share|improve this question





























    1














    I have a non-copyable class, simplified as follows:



    struct NonCopyable
    {
    NonCopyable() = default;
    NonCopyable(const NonCopyable&) = delete;
    NonCopyable& operator = (const NonCopyable&) = delete;
    NonCopyable(NonCopyable&&) = default;
    NonCopyable& operator = (NonCopyable&&) = default;
    };


    I store the objects of this class in various std::lists. At one point I have an empty std::vector of these lists, which I would like to resize to contain a fixed number of empty lists. However, this complains about the lack of a NonCopyable copy constructor, even though (as far as I can see) it shouldn't be trying to construct any NonCopyables!



    std::vector<std::list<NonCopyable>> v; // OK
    v.resize(4); // ERROR
    v.emplace_back(); // ERROR
    std::list<NonCopyable> l; // OK
    v.push_back(l); // ERROR (unsurprisingly)
    v.push_back(std::move(l)); // ERROR


    Why is this? Is there any way to do this without making the class copyable?



    I'm using VS2017 with /std:c++17 in case that makes any difference.





    Here's the full error output from just trying to resize (first two lines above).



    1>------ Build started: Project: testcore, Configuration: Debug x64 ------
    1>testcard.cpp
    1>c:program files (x86)microsoft visual studio2017communityvctoolsmsvc14.15.26726includexmemory0(881): error C2280: 'NonCopyable::NonCopyable(const NonCopyable &)': attempting to reference a deleted function
    1>[...]testcard.cpp(30): note: see declaration of 'NonCopyable::NonCopyable'
    1>[...]testcard.cpp(30): note: 'NonCopyable::NonCopyable(const NonCopyable &)': function was explicitly deleted
    1>c:program files (x86)microsoft visual studio2017communityvctoolsmsvc14.15.26726includelist(711): note: see reference to function template instantiation 'void std::_Default_allocator_traits<_Alloc>::construct<_Ty,const NonCopyable&>(_Alloc &,_Objty *const ,const NonCopyable &)' being compiled
    1> with
    1> [
    1> _Alloc=std::allocator<std::_List_node<NonCopyable,std::_Default_allocator_traits<std::allocator<NonCopyable>>::void_pointer>>,
    1> _Ty=NonCopyable,
    1> _Objty=NonCopyable
    1> ]
    1>c:program files (x86)microsoft visual studio2017communityvctoolsmsvc14.15.26726includelist(716): note: see reference to function template instantiation 'void std::_Default_allocator_traits<_Alloc>::construct<_Ty,const NonCopyable&>(_Alloc &,_Objty *const ,const NonCopyable &)' being compiled
    1> with
    1> [
    1> _Alloc=std::allocator<std::_List_node<NonCopyable,std::_Default_allocator_traits<std::allocator<NonCopyable>>::void_pointer>>,
    1> _Ty=NonCopyable,
    1> _Objty=NonCopyable
    1> ]
    1>c:program files (x86)microsoft visual studio2017communityvctoolsmsvc14.15.26726includelist(947): note: see reference to function template instantiation 'std::_List_node<_Ty,std::_Default_allocator_traits<_Alloc>::void_pointer> *std::_List_buy<_Ty,_Alloc>::_Buynode<const NonCopyable&>(std::_List_node<_Ty,std::_Default_allocator_traits<_Alloc>::void_pointer> *,std::_List_node<_Ty,std::_Default_allocator_traits<_Alloc>::void_pointer> *,const NonCopyable &)' being compiled
    1> with
    1> [
    1> _Ty=NonCopyable,
    1> _Alloc=std::allocator<NonCopyable>
    1> ]
    1>c:program files (x86)microsoft visual studio2017communityvctoolsmsvc14.15.26726includelist(950): note: see reference to function template instantiation 'std::_List_node<_Ty,std::_Default_allocator_traits<_Alloc>::void_pointer> *std::_List_buy<_Ty,_Alloc>::_Buynode<const NonCopyable&>(std::_List_node<_Ty,std::_Default_allocator_traits<_Alloc>::void_pointer> *,std::_List_node<_Ty,std::_Default_allocator_traits<_Alloc>::void_pointer> *,const NonCopyable &)' being compiled
    1> with
    1> [
    1> _Ty=NonCopyable,
    1> _Alloc=std::allocator<NonCopyable>
    1> ]
    1>c:program files (x86)microsoft visual studio2017communityvctoolsmsvc14.15.26726includelist(1308): note: see reference to function template instantiation 'void std::list<NonCopyable,std::allocator<_Ty>>::_Insert<const NonCopyable&>(std::_List_unchecked_const_iterator<std::_List_val<std::_List_simple_types<_Ty>>,std::_Iterator_base0>,const NonCopyable &)' being compiled
    1> with
    1> [
    1> _Ty=NonCopyable
    1> ]
    1>c:program files (x86)microsoft visual studio2017communityvctoolsmsvc14.15.26726includelist(1308): note: see reference to function template instantiation 'void std::list<NonCopyable,std::allocator<_Ty>>::_Insert<const NonCopyable&>(std::_List_unchecked_const_iterator<std::_List_val<std::_List_simple_types<_Ty>>,std::_Iterator_base0>,const NonCopyable &)' being compiled
    1> with
    1> [
    1> _Ty=NonCopyable
    1> ]
    1>c:program files (x86)microsoft visual studio2017communityvctoolsmsvc14.15.26726includelist(1265): note: see reference to function template instantiation 'void std::list<NonCopyable,std::allocator<_Ty>>::_Insert_range<_Iter>(std::_List_unchecked_const_iterator<std::_List_val<std::_List_simple_types<_Ty>>,std::_Iterator_base0>,_Iter,_Iter,std::forward_iterator_tag)' being compiled
    1> with
    1> [
    1> _Ty=NonCopyable,
    1> _Iter=std::_List_const_iterator<std::_List_val<std::_List_simple_types<NonCopyable>>>
    1> ]
    1>c:program files (x86)microsoft visual studio2017communityvctoolsmsvc14.15.26726includelist(1264): note: see reference to function template instantiation 'void std::list<NonCopyable,std::allocator<_Ty>>::_Insert_range<_Iter>(std::_List_unchecked_const_iterator<std::_List_val<std::_List_simple_types<_Ty>>,std::_Iterator_base0>,_Iter,_Iter,std::forward_iterator_tag)' being compiled
    1> with
    1> [
    1> _Ty=NonCopyable,
    1> _Iter=std::_List_const_iterator<std::_List_val<std::_List_simple_types<NonCopyable>>>
    1> ]
    1>c:program files (x86)microsoft visual studio2017communityvctoolsmsvc14.15.26726includelist(800): note: see reference to function template instantiation 'std::_List_iterator<std::_List_val<std::_List_simple_types<_Ty>>> std::list<_Ty,std::allocator<_Ty>>::insert<std::_List_const_iterator<std::_List_val<std::_List_simple_types<_Ty>>>,void>(std::_List_const_iterator<std::_List_val<std::_List_simple_types<_Ty>>>,_Iter,_Iter)' being compiled
    1> with
    1> [
    1> _Ty=NonCopyable,
    1> _Iter=std::_List_const_iterator<std::_List_val<std::_List_simple_types<NonCopyable>>>
    1> ]
    1>c:program files (x86)microsoft visual studio2017communityvctoolsmsvc14.15.26726includelist(800): note: see reference to function template instantiation 'std::_List_iterator<std::_List_val<std::_List_simple_types<_Ty>>> std::list<_Ty,std::allocator<_Ty>>::insert<std::_List_const_iterator<std::_List_val<std::_List_simple_types<_Ty>>>,void>(std::_List_const_iterator<std::_List_val<std::_List_simple_types<_Ty>>>,_Iter,_Iter)' being compiled
    1> with
    1> [
    1> _Ty=NonCopyable,
    1> _Iter=std::_List_const_iterator<std::_List_val<std::_List_simple_types<NonCopyable>>>
    1> ]
    1>c:program files (x86)microsoft visual studio2017communityvctoolsmsvc14.15.26726includelist(796): note: while compiling class template member function 'std::list<NonCopyable,std::allocator<_Ty>>::list(const std::list<_Ty,std::allocator<_Ty>> &)'
    1> with
    1> [
    1> _Ty=NonCopyable
    1> ]
    1>c:program files (x86)microsoft visual studio2017communityvctoolsmsvc14.15.26726includexmemory0(881): note: see reference to function template instantiation 'std::list<NonCopyable,std::allocator<_Ty>>::list(const std::list<_Ty,std::allocator<_Ty>> &)' being compiled
    1> with
    1> [
    1> _Ty=NonCopyable
    1> ]
    1>c:program files (x86)microsoft visual studio2017communityvctoolsmsvc14.15.26726includevector(1812): note: see reference to class template instantiation 'std::list<NonCopyable,std::allocator<_Ty>>' being compiled
    1> with
    1> [
    1> _Ty=NonCopyable
    1> ]
    1>c:program files (x86)microsoft visual studio2017communityvctoolsmsvc14.15.26726includevector(1811): note: while compiling class template member function 'std::list<NonCopyable,std::allocator<_Ty>> *std::vector<std::list<_Ty,std::allocator<_Ty>>,std::allocator<std::list<_Ty,std::allocator<_Ty>>>>::_Udefault(std::list<_Ty,std::allocator<_Ty>> *,const unsigned __int64)'
    1> with
    1> [
    1> _Ty=NonCopyable
    1> ]
    1>c:program files (x86)microsoft visual studio2017communityvctoolsmsvc14.15.26726includevector(1479): note: see reference to function template instantiation 'std::list<NonCopyable,std::allocator<_Ty>> *std::vector<std::list<_Ty,std::allocator<_Ty>>,std::allocator<std::list<_Ty,std::allocator<_Ty>>>>::_Udefault(std::list<_Ty,std::allocator<_Ty>> *,const unsigned __int64)' being compiled
    1> with
    1> [
    1> _Ty=NonCopyable
    1> ]
    1>[...]testcard.cpp(37): note: see reference to class template instantiation 'std::vector<std::list<NonCopyable,std::allocator<_Ty>>,std::allocator<std::list<_Ty,std::allocator<_Ty>>>>' being compiled
    1> with
    1> [
    1> _Ty=NonCopyable
    1> ]
    1>Done building project "testcore.vcxproj" -- FAILED.
    ========== Build: 0 succeeded, 1 failed, 2 up-to-date, 0 skipped ==========









    share|improve this question



























      1












      1








      1


      2





      I have a non-copyable class, simplified as follows:



      struct NonCopyable
      {
      NonCopyable() = default;
      NonCopyable(const NonCopyable&) = delete;
      NonCopyable& operator = (const NonCopyable&) = delete;
      NonCopyable(NonCopyable&&) = default;
      NonCopyable& operator = (NonCopyable&&) = default;
      };


      I store the objects of this class in various std::lists. At one point I have an empty std::vector of these lists, which I would like to resize to contain a fixed number of empty lists. However, this complains about the lack of a NonCopyable copy constructor, even though (as far as I can see) it shouldn't be trying to construct any NonCopyables!



      std::vector<std::list<NonCopyable>> v; // OK
      v.resize(4); // ERROR
      v.emplace_back(); // ERROR
      std::list<NonCopyable> l; // OK
      v.push_back(l); // ERROR (unsurprisingly)
      v.push_back(std::move(l)); // ERROR


      Why is this? Is there any way to do this without making the class copyable?



      I'm using VS2017 with /std:c++17 in case that makes any difference.





      Here's the full error output from just trying to resize (first two lines above).



      1>------ Build started: Project: testcore, Configuration: Debug x64 ------
      1>testcard.cpp
      1>c:program files (x86)microsoft visual studio2017communityvctoolsmsvc14.15.26726includexmemory0(881): error C2280: 'NonCopyable::NonCopyable(const NonCopyable &)': attempting to reference a deleted function
      1>[...]testcard.cpp(30): note: see declaration of 'NonCopyable::NonCopyable'
      1>[...]testcard.cpp(30): note: 'NonCopyable::NonCopyable(const NonCopyable &)': function was explicitly deleted
      1>c:program files (x86)microsoft visual studio2017communityvctoolsmsvc14.15.26726includelist(711): note: see reference to function template instantiation 'void std::_Default_allocator_traits<_Alloc>::construct<_Ty,const NonCopyable&>(_Alloc &,_Objty *const ,const NonCopyable &)' being compiled
      1> with
      1> [
      1> _Alloc=std::allocator<std::_List_node<NonCopyable,std::_Default_allocator_traits<std::allocator<NonCopyable>>::void_pointer>>,
      1> _Ty=NonCopyable,
      1> _Objty=NonCopyable
      1> ]
      1>c:program files (x86)microsoft visual studio2017communityvctoolsmsvc14.15.26726includelist(716): note: see reference to function template instantiation 'void std::_Default_allocator_traits<_Alloc>::construct<_Ty,const NonCopyable&>(_Alloc &,_Objty *const ,const NonCopyable &)' being compiled
      1> with
      1> [
      1> _Alloc=std::allocator<std::_List_node<NonCopyable,std::_Default_allocator_traits<std::allocator<NonCopyable>>::void_pointer>>,
      1> _Ty=NonCopyable,
      1> _Objty=NonCopyable
      1> ]
      1>c:program files (x86)microsoft visual studio2017communityvctoolsmsvc14.15.26726includelist(947): note: see reference to function template instantiation 'std::_List_node<_Ty,std::_Default_allocator_traits<_Alloc>::void_pointer> *std::_List_buy<_Ty,_Alloc>::_Buynode<const NonCopyable&>(std::_List_node<_Ty,std::_Default_allocator_traits<_Alloc>::void_pointer> *,std::_List_node<_Ty,std::_Default_allocator_traits<_Alloc>::void_pointer> *,const NonCopyable &)' being compiled
      1> with
      1> [
      1> _Ty=NonCopyable,
      1> _Alloc=std::allocator<NonCopyable>
      1> ]
      1>c:program files (x86)microsoft visual studio2017communityvctoolsmsvc14.15.26726includelist(950): note: see reference to function template instantiation 'std::_List_node<_Ty,std::_Default_allocator_traits<_Alloc>::void_pointer> *std::_List_buy<_Ty,_Alloc>::_Buynode<const NonCopyable&>(std::_List_node<_Ty,std::_Default_allocator_traits<_Alloc>::void_pointer> *,std::_List_node<_Ty,std::_Default_allocator_traits<_Alloc>::void_pointer> *,const NonCopyable &)' being compiled
      1> with
      1> [
      1> _Ty=NonCopyable,
      1> _Alloc=std::allocator<NonCopyable>
      1> ]
      1>c:program files (x86)microsoft visual studio2017communityvctoolsmsvc14.15.26726includelist(1308): note: see reference to function template instantiation 'void std::list<NonCopyable,std::allocator<_Ty>>::_Insert<const NonCopyable&>(std::_List_unchecked_const_iterator<std::_List_val<std::_List_simple_types<_Ty>>,std::_Iterator_base0>,const NonCopyable &)' being compiled
      1> with
      1> [
      1> _Ty=NonCopyable
      1> ]
      1>c:program files (x86)microsoft visual studio2017communityvctoolsmsvc14.15.26726includelist(1308): note: see reference to function template instantiation 'void std::list<NonCopyable,std::allocator<_Ty>>::_Insert<const NonCopyable&>(std::_List_unchecked_const_iterator<std::_List_val<std::_List_simple_types<_Ty>>,std::_Iterator_base0>,const NonCopyable &)' being compiled
      1> with
      1> [
      1> _Ty=NonCopyable
      1> ]
      1>c:program files (x86)microsoft visual studio2017communityvctoolsmsvc14.15.26726includelist(1265): note: see reference to function template instantiation 'void std::list<NonCopyable,std::allocator<_Ty>>::_Insert_range<_Iter>(std::_List_unchecked_const_iterator<std::_List_val<std::_List_simple_types<_Ty>>,std::_Iterator_base0>,_Iter,_Iter,std::forward_iterator_tag)' being compiled
      1> with
      1> [
      1> _Ty=NonCopyable,
      1> _Iter=std::_List_const_iterator<std::_List_val<std::_List_simple_types<NonCopyable>>>
      1> ]
      1>c:program files (x86)microsoft visual studio2017communityvctoolsmsvc14.15.26726includelist(1264): note: see reference to function template instantiation 'void std::list<NonCopyable,std::allocator<_Ty>>::_Insert_range<_Iter>(std::_List_unchecked_const_iterator<std::_List_val<std::_List_simple_types<_Ty>>,std::_Iterator_base0>,_Iter,_Iter,std::forward_iterator_tag)' being compiled
      1> with
      1> [
      1> _Ty=NonCopyable,
      1> _Iter=std::_List_const_iterator<std::_List_val<std::_List_simple_types<NonCopyable>>>
      1> ]
      1>c:program files (x86)microsoft visual studio2017communityvctoolsmsvc14.15.26726includelist(800): note: see reference to function template instantiation 'std::_List_iterator<std::_List_val<std::_List_simple_types<_Ty>>> std::list<_Ty,std::allocator<_Ty>>::insert<std::_List_const_iterator<std::_List_val<std::_List_simple_types<_Ty>>>,void>(std::_List_const_iterator<std::_List_val<std::_List_simple_types<_Ty>>>,_Iter,_Iter)' being compiled
      1> with
      1> [
      1> _Ty=NonCopyable,
      1> _Iter=std::_List_const_iterator<std::_List_val<std::_List_simple_types<NonCopyable>>>
      1> ]
      1>c:program files (x86)microsoft visual studio2017communityvctoolsmsvc14.15.26726includelist(800): note: see reference to function template instantiation 'std::_List_iterator<std::_List_val<std::_List_simple_types<_Ty>>> std::list<_Ty,std::allocator<_Ty>>::insert<std::_List_const_iterator<std::_List_val<std::_List_simple_types<_Ty>>>,void>(std::_List_const_iterator<std::_List_val<std::_List_simple_types<_Ty>>>,_Iter,_Iter)' being compiled
      1> with
      1> [
      1> _Ty=NonCopyable,
      1> _Iter=std::_List_const_iterator<std::_List_val<std::_List_simple_types<NonCopyable>>>
      1> ]
      1>c:program files (x86)microsoft visual studio2017communityvctoolsmsvc14.15.26726includelist(796): note: while compiling class template member function 'std::list<NonCopyable,std::allocator<_Ty>>::list(const std::list<_Ty,std::allocator<_Ty>> &)'
      1> with
      1> [
      1> _Ty=NonCopyable
      1> ]
      1>c:program files (x86)microsoft visual studio2017communityvctoolsmsvc14.15.26726includexmemory0(881): note: see reference to function template instantiation 'std::list<NonCopyable,std::allocator<_Ty>>::list(const std::list<_Ty,std::allocator<_Ty>> &)' being compiled
      1> with
      1> [
      1> _Ty=NonCopyable
      1> ]
      1>c:program files (x86)microsoft visual studio2017communityvctoolsmsvc14.15.26726includevector(1812): note: see reference to class template instantiation 'std::list<NonCopyable,std::allocator<_Ty>>' being compiled
      1> with
      1> [
      1> _Ty=NonCopyable
      1> ]
      1>c:program files (x86)microsoft visual studio2017communityvctoolsmsvc14.15.26726includevector(1811): note: while compiling class template member function 'std::list<NonCopyable,std::allocator<_Ty>> *std::vector<std::list<_Ty,std::allocator<_Ty>>,std::allocator<std::list<_Ty,std::allocator<_Ty>>>>::_Udefault(std::list<_Ty,std::allocator<_Ty>> *,const unsigned __int64)'
      1> with
      1> [
      1> _Ty=NonCopyable
      1> ]
      1>c:program files (x86)microsoft visual studio2017communityvctoolsmsvc14.15.26726includevector(1479): note: see reference to function template instantiation 'std::list<NonCopyable,std::allocator<_Ty>> *std::vector<std::list<_Ty,std::allocator<_Ty>>,std::allocator<std::list<_Ty,std::allocator<_Ty>>>>::_Udefault(std::list<_Ty,std::allocator<_Ty>> *,const unsigned __int64)' being compiled
      1> with
      1> [
      1> _Ty=NonCopyable
      1> ]
      1>[...]testcard.cpp(37): note: see reference to class template instantiation 'std::vector<std::list<NonCopyable,std::allocator<_Ty>>,std::allocator<std::list<_Ty,std::allocator<_Ty>>>>' being compiled
      1> with
      1> [
      1> _Ty=NonCopyable
      1> ]
      1>Done building project "testcore.vcxproj" -- FAILED.
      ========== Build: 0 succeeded, 1 failed, 2 up-to-date, 0 skipped ==========









      share|improve this question















      I have a non-copyable class, simplified as follows:



      struct NonCopyable
      {
      NonCopyable() = default;
      NonCopyable(const NonCopyable&) = delete;
      NonCopyable& operator = (const NonCopyable&) = delete;
      NonCopyable(NonCopyable&&) = default;
      NonCopyable& operator = (NonCopyable&&) = default;
      };


      I store the objects of this class in various std::lists. At one point I have an empty std::vector of these lists, which I would like to resize to contain a fixed number of empty lists. However, this complains about the lack of a NonCopyable copy constructor, even though (as far as I can see) it shouldn't be trying to construct any NonCopyables!



      std::vector<std::list<NonCopyable>> v; // OK
      v.resize(4); // ERROR
      v.emplace_back(); // ERROR
      std::list<NonCopyable> l; // OK
      v.push_back(l); // ERROR (unsurprisingly)
      v.push_back(std::move(l)); // ERROR


      Why is this? Is there any way to do this without making the class copyable?



      I'm using VS2017 with /std:c++17 in case that makes any difference.





      Here's the full error output from just trying to resize (first two lines above).



      1>------ Build started: Project: testcore, Configuration: Debug x64 ------
      1>testcard.cpp
      1>c:program files (x86)microsoft visual studio2017communityvctoolsmsvc14.15.26726includexmemory0(881): error C2280: 'NonCopyable::NonCopyable(const NonCopyable &)': attempting to reference a deleted function
      1>[...]testcard.cpp(30): note: see declaration of 'NonCopyable::NonCopyable'
      1>[...]testcard.cpp(30): note: 'NonCopyable::NonCopyable(const NonCopyable &)': function was explicitly deleted
      1>c:program files (x86)microsoft visual studio2017communityvctoolsmsvc14.15.26726includelist(711): note: see reference to function template instantiation 'void std::_Default_allocator_traits<_Alloc>::construct<_Ty,const NonCopyable&>(_Alloc &,_Objty *const ,const NonCopyable &)' being compiled
      1> with
      1> [
      1> _Alloc=std::allocator<std::_List_node<NonCopyable,std::_Default_allocator_traits<std::allocator<NonCopyable>>::void_pointer>>,
      1> _Ty=NonCopyable,
      1> _Objty=NonCopyable
      1> ]
      1>c:program files (x86)microsoft visual studio2017communityvctoolsmsvc14.15.26726includelist(716): note: see reference to function template instantiation 'void std::_Default_allocator_traits<_Alloc>::construct<_Ty,const NonCopyable&>(_Alloc &,_Objty *const ,const NonCopyable &)' being compiled
      1> with
      1> [
      1> _Alloc=std::allocator<std::_List_node<NonCopyable,std::_Default_allocator_traits<std::allocator<NonCopyable>>::void_pointer>>,
      1> _Ty=NonCopyable,
      1> _Objty=NonCopyable
      1> ]
      1>c:program files (x86)microsoft visual studio2017communityvctoolsmsvc14.15.26726includelist(947): note: see reference to function template instantiation 'std::_List_node<_Ty,std::_Default_allocator_traits<_Alloc>::void_pointer> *std::_List_buy<_Ty,_Alloc>::_Buynode<const NonCopyable&>(std::_List_node<_Ty,std::_Default_allocator_traits<_Alloc>::void_pointer> *,std::_List_node<_Ty,std::_Default_allocator_traits<_Alloc>::void_pointer> *,const NonCopyable &)' being compiled
      1> with
      1> [
      1> _Ty=NonCopyable,
      1> _Alloc=std::allocator<NonCopyable>
      1> ]
      1>c:program files (x86)microsoft visual studio2017communityvctoolsmsvc14.15.26726includelist(950): note: see reference to function template instantiation 'std::_List_node<_Ty,std::_Default_allocator_traits<_Alloc>::void_pointer> *std::_List_buy<_Ty,_Alloc>::_Buynode<const NonCopyable&>(std::_List_node<_Ty,std::_Default_allocator_traits<_Alloc>::void_pointer> *,std::_List_node<_Ty,std::_Default_allocator_traits<_Alloc>::void_pointer> *,const NonCopyable &)' being compiled
      1> with
      1> [
      1> _Ty=NonCopyable,
      1> _Alloc=std::allocator<NonCopyable>
      1> ]
      1>c:program files (x86)microsoft visual studio2017communityvctoolsmsvc14.15.26726includelist(1308): note: see reference to function template instantiation 'void std::list<NonCopyable,std::allocator<_Ty>>::_Insert<const NonCopyable&>(std::_List_unchecked_const_iterator<std::_List_val<std::_List_simple_types<_Ty>>,std::_Iterator_base0>,const NonCopyable &)' being compiled
      1> with
      1> [
      1> _Ty=NonCopyable
      1> ]
      1>c:program files (x86)microsoft visual studio2017communityvctoolsmsvc14.15.26726includelist(1308): note: see reference to function template instantiation 'void std::list<NonCopyable,std::allocator<_Ty>>::_Insert<const NonCopyable&>(std::_List_unchecked_const_iterator<std::_List_val<std::_List_simple_types<_Ty>>,std::_Iterator_base0>,const NonCopyable &)' being compiled
      1> with
      1> [
      1> _Ty=NonCopyable
      1> ]
      1>c:program files (x86)microsoft visual studio2017communityvctoolsmsvc14.15.26726includelist(1265): note: see reference to function template instantiation 'void std::list<NonCopyable,std::allocator<_Ty>>::_Insert_range<_Iter>(std::_List_unchecked_const_iterator<std::_List_val<std::_List_simple_types<_Ty>>,std::_Iterator_base0>,_Iter,_Iter,std::forward_iterator_tag)' being compiled
      1> with
      1> [
      1> _Ty=NonCopyable,
      1> _Iter=std::_List_const_iterator<std::_List_val<std::_List_simple_types<NonCopyable>>>
      1> ]
      1>c:program files (x86)microsoft visual studio2017communityvctoolsmsvc14.15.26726includelist(1264): note: see reference to function template instantiation 'void std::list<NonCopyable,std::allocator<_Ty>>::_Insert_range<_Iter>(std::_List_unchecked_const_iterator<std::_List_val<std::_List_simple_types<_Ty>>,std::_Iterator_base0>,_Iter,_Iter,std::forward_iterator_tag)' being compiled
      1> with
      1> [
      1> _Ty=NonCopyable,
      1> _Iter=std::_List_const_iterator<std::_List_val<std::_List_simple_types<NonCopyable>>>
      1> ]
      1>c:program files (x86)microsoft visual studio2017communityvctoolsmsvc14.15.26726includelist(800): note: see reference to function template instantiation 'std::_List_iterator<std::_List_val<std::_List_simple_types<_Ty>>> std::list<_Ty,std::allocator<_Ty>>::insert<std::_List_const_iterator<std::_List_val<std::_List_simple_types<_Ty>>>,void>(std::_List_const_iterator<std::_List_val<std::_List_simple_types<_Ty>>>,_Iter,_Iter)' being compiled
      1> with
      1> [
      1> _Ty=NonCopyable,
      1> _Iter=std::_List_const_iterator<std::_List_val<std::_List_simple_types<NonCopyable>>>
      1> ]
      1>c:program files (x86)microsoft visual studio2017communityvctoolsmsvc14.15.26726includelist(800): note: see reference to function template instantiation 'std::_List_iterator<std::_List_val<std::_List_simple_types<_Ty>>> std::list<_Ty,std::allocator<_Ty>>::insert<std::_List_const_iterator<std::_List_val<std::_List_simple_types<_Ty>>>,void>(std::_List_const_iterator<std::_List_val<std::_List_simple_types<_Ty>>>,_Iter,_Iter)' being compiled
      1> with
      1> [
      1> _Ty=NonCopyable,
      1> _Iter=std::_List_const_iterator<std::_List_val<std::_List_simple_types<NonCopyable>>>
      1> ]
      1>c:program files (x86)microsoft visual studio2017communityvctoolsmsvc14.15.26726includelist(796): note: while compiling class template member function 'std::list<NonCopyable,std::allocator<_Ty>>::list(const std::list<_Ty,std::allocator<_Ty>> &)'
      1> with
      1> [
      1> _Ty=NonCopyable
      1> ]
      1>c:program files (x86)microsoft visual studio2017communityvctoolsmsvc14.15.26726includexmemory0(881): note: see reference to function template instantiation 'std::list<NonCopyable,std::allocator<_Ty>>::list(const std::list<_Ty,std::allocator<_Ty>> &)' being compiled
      1> with
      1> [
      1> _Ty=NonCopyable
      1> ]
      1>c:program files (x86)microsoft visual studio2017communityvctoolsmsvc14.15.26726includevector(1812): note: see reference to class template instantiation 'std::list<NonCopyable,std::allocator<_Ty>>' being compiled
      1> with
      1> [
      1> _Ty=NonCopyable
      1> ]
      1>c:program files (x86)microsoft visual studio2017communityvctoolsmsvc14.15.26726includevector(1811): note: while compiling class template member function 'std::list<NonCopyable,std::allocator<_Ty>> *std::vector<std::list<_Ty,std::allocator<_Ty>>,std::allocator<std::list<_Ty,std::allocator<_Ty>>>>::_Udefault(std::list<_Ty,std::allocator<_Ty>> *,const unsigned __int64)'
      1> with
      1> [
      1> _Ty=NonCopyable
      1> ]
      1>c:program files (x86)microsoft visual studio2017communityvctoolsmsvc14.15.26726includevector(1479): note: see reference to function template instantiation 'std::list<NonCopyable,std::allocator<_Ty>> *std::vector<std::list<_Ty,std::allocator<_Ty>>,std::allocator<std::list<_Ty,std::allocator<_Ty>>>>::_Udefault(std::list<_Ty,std::allocator<_Ty>> *,const unsigned __int64)' being compiled
      1> with
      1> [
      1> _Ty=NonCopyable
      1> ]
      1>[...]testcard.cpp(37): note: see reference to class template instantiation 'std::vector<std::list<NonCopyable,std::allocator<_Ty>>,std::allocator<std::list<_Ty,std::allocator<_Ty>>>>' being compiled
      1> with
      1> [
      1> _Ty=NonCopyable
      1> ]
      1>Done building project "testcore.vcxproj" -- FAILED.
      ========== Build: 0 succeeded, 1 failed, 2 up-to-date, 0 skipped ==========






      c++ c++11 stl






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 22 at 14:11

























      asked Nov 22 at 13:25









      Uri Zarfaty

      733515




      733515
























          2 Answers
          2






          active

          oldest

          votes


















          3














          std::list is not noexcept-movable, but is copyable. Therefore, std::vector prefers list's the copy-constructor over its move-constructor, regardless.



          To work around the issue, you have to wrap your std::list in a class that is not copyable.






          share|improve this answer























          • Thanks. What if the NonCopyable class was also not movable? (Moving objects between lists would still be possible I believe, since it doesn't invalidate references,)
            – Uri Zarfaty
            Nov 22 at 15:02






          • 1




            @UriZarfaty It would be possible to move the list's nodes around using splice, but std::vector does not know about it.
            – j6t
            Nov 22 at 15:04






          • 1




            @StoryTeller It is not exactly QoI, but a matter of following the Standard literally. I do not see a noexcept specification on the move constructor in the list synopsis. That said, I agree that the Clang's and GCC's behavior is preferable.
            – j6t
            Nov 22 at 15:42








          • 1




            @j6t - The standard has a debatable QoI too. Well, quality of specification would be more exact, but the point still holds.
            – StoryTeller
            Nov 22 at 15:58






          • 1




            These Requires clauses are directives for the programmer, not the compiler. If the conditions are violated, you get what you deserve; at best it does not compile, at worst it is undefined behavior.
            – j6t
            Nov 23 at 10:13



















          2














          As @j6t pointed out, it seems it can't be done. A vector with a std::list with non-copyable elements can not be expanded according to the standard (...). If it was my private project I'd actually consider something like this:



          #include <iostream>
          #include <vector>
          #include <list>

          namespace xxx {
          // <flame_bait>
          template<class T, class Enable = void>
          struct list : std::list<T> {
          list() : std::list<T>() {}
          list(list&&) = default;
          list& operator=(list&&) = default;
          list(const list&) = delete;
          list& operator=(const list&) = delete;
          };

          template<class T>
          struct list<T, typename std::enable_if<std::is_copy_constructible<T>::value>::type> : std::list<T> {};
          // </flame_bait>
          }

          struct NonCopyable
          {
          int m_id;
          NonCopyable(int id = 0) : m_id(id) {}
          NonCopyable(const NonCopyable&) = delete;
          NonCopyable& operator = (const NonCopyable&) = delete;
          NonCopyable(NonCopyable&&) noexcept = default;
          NonCopyable& operator = (NonCopyable&&) noexcept = default;
          ~NonCopyable() = default;
          friend std::ostream& operator<<(std::ostream&, const NonCopyable&);
          };

          std::ostream& operator<<(std::ostream& os, const NonCopyable& nc) {
          os << "I am not a free man, I am number " << nc.m_id;
          return os;
          }

          int main() {
          std::vector<xxx::list<NonCopyable>> v;
          v.resize(4); // now working

          int id = 0;
          for (auto& l : v) {
          l.emplace_back(++id); // emplace_back one NonCopyable per list
          }

          xxx::list<NonCopyable> li; // Create a separate list
          li.emplace_back(++id); // create one...
          v.emplace_back(std::move(li)); // and move list to vector is now working

          for (auto& l : v) {
          for (auto& nc : l) {
          std::cout << nc << "n";
          }
          }
          }


          Expected output:



          I am not a free man, I am number 1
          I am not a free man, I am number 2
          I am not a free man, I am number 3
          I am not a free man, I am number 4
          I am not a free man, I am number 5





          share|improve this answer























          • Seems I missed the part where v.resize(4); fails. What's the error message from that line?
            – Ted Lyngmo
            Nov 22 at 13:59






          • 1




            error C2280: 'NonCopyable::NonCopyable(const NonCopyable &)': attempting to reference a deleted function. I've added the full error output for that to the post.
            – Uri Zarfaty
            Nov 22 at 14:11






          • 1




            Great! How odd though ... :-) I'll give it a try in VS when I get home.
            – Ted Lyngmo
            Nov 22 at 14:14












          • Just to make it worse: v.reserve(4); gives the same error.
            – Ted Lyngmo
            Nov 22 at 15:20






          • 1




            I added a xxx::list replacement for std::list that hopefully should work as a container for both copyable and non-copyable objects. I''m terrible with templates though so be aware ...
            – Ted Lyngmo
            Nov 22 at 17:47











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53432012%2fnon-copyable-elements-in-a-stdvector-of-stdlists%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          2 Answers
          2






          active

          oldest

          votes








          2 Answers
          2






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          3














          std::list is not noexcept-movable, but is copyable. Therefore, std::vector prefers list's the copy-constructor over its move-constructor, regardless.



          To work around the issue, you have to wrap your std::list in a class that is not copyable.






          share|improve this answer























          • Thanks. What if the NonCopyable class was also not movable? (Moving objects between lists would still be possible I believe, since it doesn't invalidate references,)
            – Uri Zarfaty
            Nov 22 at 15:02






          • 1




            @UriZarfaty It would be possible to move the list's nodes around using splice, but std::vector does not know about it.
            – j6t
            Nov 22 at 15:04






          • 1




            @StoryTeller It is not exactly QoI, but a matter of following the Standard literally. I do not see a noexcept specification on the move constructor in the list synopsis. That said, I agree that the Clang's and GCC's behavior is preferable.
            – j6t
            Nov 22 at 15:42








          • 1




            @j6t - The standard has a debatable QoI too. Well, quality of specification would be more exact, but the point still holds.
            – StoryTeller
            Nov 22 at 15:58






          • 1




            These Requires clauses are directives for the programmer, not the compiler. If the conditions are violated, you get what you deserve; at best it does not compile, at worst it is undefined behavior.
            – j6t
            Nov 23 at 10:13
















          3














          std::list is not noexcept-movable, but is copyable. Therefore, std::vector prefers list's the copy-constructor over its move-constructor, regardless.



          To work around the issue, you have to wrap your std::list in a class that is not copyable.






          share|improve this answer























          • Thanks. What if the NonCopyable class was also not movable? (Moving objects between lists would still be possible I believe, since it doesn't invalidate references,)
            – Uri Zarfaty
            Nov 22 at 15:02






          • 1




            @UriZarfaty It would be possible to move the list's nodes around using splice, but std::vector does not know about it.
            – j6t
            Nov 22 at 15:04






          • 1




            @StoryTeller It is not exactly QoI, but a matter of following the Standard literally. I do not see a noexcept specification on the move constructor in the list synopsis. That said, I agree that the Clang's and GCC's behavior is preferable.
            – j6t
            Nov 22 at 15:42








          • 1




            @j6t - The standard has a debatable QoI too. Well, quality of specification would be more exact, but the point still holds.
            – StoryTeller
            Nov 22 at 15:58






          • 1




            These Requires clauses are directives for the programmer, not the compiler. If the conditions are violated, you get what you deserve; at best it does not compile, at worst it is undefined behavior.
            – j6t
            Nov 23 at 10:13














          3












          3








          3






          std::list is not noexcept-movable, but is copyable. Therefore, std::vector prefers list's the copy-constructor over its move-constructor, regardless.



          To work around the issue, you have to wrap your std::list in a class that is not copyable.






          share|improve this answer














          std::list is not noexcept-movable, but is copyable. Therefore, std::vector prefers list's the copy-constructor over its move-constructor, regardless.



          To work around the issue, you have to wrap your std::list in a class that is not copyable.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 22 at 14:50

























          answered Nov 22 at 14:44









          j6t

          1,171138




          1,171138












          • Thanks. What if the NonCopyable class was also not movable? (Moving objects between lists would still be possible I believe, since it doesn't invalidate references,)
            – Uri Zarfaty
            Nov 22 at 15:02






          • 1




            @UriZarfaty It would be possible to move the list's nodes around using splice, but std::vector does not know about it.
            – j6t
            Nov 22 at 15:04






          • 1




            @StoryTeller It is not exactly QoI, but a matter of following the Standard literally. I do not see a noexcept specification on the move constructor in the list synopsis. That said, I agree that the Clang's and GCC's behavior is preferable.
            – j6t
            Nov 22 at 15:42








          • 1




            @j6t - The standard has a debatable QoI too. Well, quality of specification would be more exact, but the point still holds.
            – StoryTeller
            Nov 22 at 15:58






          • 1




            These Requires clauses are directives for the programmer, not the compiler. If the conditions are violated, you get what you deserve; at best it does not compile, at worst it is undefined behavior.
            – j6t
            Nov 23 at 10:13


















          • Thanks. What if the NonCopyable class was also not movable? (Moving objects between lists would still be possible I believe, since it doesn't invalidate references,)
            – Uri Zarfaty
            Nov 22 at 15:02






          • 1




            @UriZarfaty It would be possible to move the list's nodes around using splice, but std::vector does not know about it.
            – j6t
            Nov 22 at 15:04






          • 1




            @StoryTeller It is not exactly QoI, but a matter of following the Standard literally. I do not see a noexcept specification on the move constructor in the list synopsis. That said, I agree that the Clang's and GCC's behavior is preferable.
            – j6t
            Nov 22 at 15:42








          • 1




            @j6t - The standard has a debatable QoI too. Well, quality of specification would be more exact, but the point still holds.
            – StoryTeller
            Nov 22 at 15:58






          • 1




            These Requires clauses are directives for the programmer, not the compiler. If the conditions are violated, you get what you deserve; at best it does not compile, at worst it is undefined behavior.
            – j6t
            Nov 23 at 10:13
















          Thanks. What if the NonCopyable class was also not movable? (Moving objects between lists would still be possible I believe, since it doesn't invalidate references,)
          – Uri Zarfaty
          Nov 22 at 15:02




          Thanks. What if the NonCopyable class was also not movable? (Moving objects between lists would still be possible I believe, since it doesn't invalidate references,)
          – Uri Zarfaty
          Nov 22 at 15:02




          1




          1




          @UriZarfaty It would be possible to move the list's nodes around using splice, but std::vector does not know about it.
          – j6t
          Nov 22 at 15:04




          @UriZarfaty It would be possible to move the list's nodes around using splice, but std::vector does not know about it.
          – j6t
          Nov 22 at 15:04




          1




          1




          @StoryTeller It is not exactly QoI, but a matter of following the Standard literally. I do not see a noexcept specification on the move constructor in the list synopsis. That said, I agree that the Clang's and GCC's behavior is preferable.
          – j6t
          Nov 22 at 15:42






          @StoryTeller It is not exactly QoI, but a matter of following the Standard literally. I do not see a noexcept specification on the move constructor in the list synopsis. That said, I agree that the Clang's and GCC's behavior is preferable.
          – j6t
          Nov 22 at 15:42






          1




          1




          @j6t - The standard has a debatable QoI too. Well, quality of specification would be more exact, but the point still holds.
          – StoryTeller
          Nov 22 at 15:58




          @j6t - The standard has a debatable QoI too. Well, quality of specification would be more exact, but the point still holds.
          – StoryTeller
          Nov 22 at 15:58




          1




          1




          These Requires clauses are directives for the programmer, not the compiler. If the conditions are violated, you get what you deserve; at best it does not compile, at worst it is undefined behavior.
          – j6t
          Nov 23 at 10:13




          These Requires clauses are directives for the programmer, not the compiler. If the conditions are violated, you get what you deserve; at best it does not compile, at worst it is undefined behavior.
          – j6t
          Nov 23 at 10:13













          2














          As @j6t pointed out, it seems it can't be done. A vector with a std::list with non-copyable elements can not be expanded according to the standard (...). If it was my private project I'd actually consider something like this:



          #include <iostream>
          #include <vector>
          #include <list>

          namespace xxx {
          // <flame_bait>
          template<class T, class Enable = void>
          struct list : std::list<T> {
          list() : std::list<T>() {}
          list(list&&) = default;
          list& operator=(list&&) = default;
          list(const list&) = delete;
          list& operator=(const list&) = delete;
          };

          template<class T>
          struct list<T, typename std::enable_if<std::is_copy_constructible<T>::value>::type> : std::list<T> {};
          // </flame_bait>
          }

          struct NonCopyable
          {
          int m_id;
          NonCopyable(int id = 0) : m_id(id) {}
          NonCopyable(const NonCopyable&) = delete;
          NonCopyable& operator = (const NonCopyable&) = delete;
          NonCopyable(NonCopyable&&) noexcept = default;
          NonCopyable& operator = (NonCopyable&&) noexcept = default;
          ~NonCopyable() = default;
          friend std::ostream& operator<<(std::ostream&, const NonCopyable&);
          };

          std::ostream& operator<<(std::ostream& os, const NonCopyable& nc) {
          os << "I am not a free man, I am number " << nc.m_id;
          return os;
          }

          int main() {
          std::vector<xxx::list<NonCopyable>> v;
          v.resize(4); // now working

          int id = 0;
          for (auto& l : v) {
          l.emplace_back(++id); // emplace_back one NonCopyable per list
          }

          xxx::list<NonCopyable> li; // Create a separate list
          li.emplace_back(++id); // create one...
          v.emplace_back(std::move(li)); // and move list to vector is now working

          for (auto& l : v) {
          for (auto& nc : l) {
          std::cout << nc << "n";
          }
          }
          }


          Expected output:



          I am not a free man, I am number 1
          I am not a free man, I am number 2
          I am not a free man, I am number 3
          I am not a free man, I am number 4
          I am not a free man, I am number 5





          share|improve this answer























          • Seems I missed the part where v.resize(4); fails. What's the error message from that line?
            – Ted Lyngmo
            Nov 22 at 13:59






          • 1




            error C2280: 'NonCopyable::NonCopyable(const NonCopyable &)': attempting to reference a deleted function. I've added the full error output for that to the post.
            – Uri Zarfaty
            Nov 22 at 14:11






          • 1




            Great! How odd though ... :-) I'll give it a try in VS when I get home.
            – Ted Lyngmo
            Nov 22 at 14:14












          • Just to make it worse: v.reserve(4); gives the same error.
            – Ted Lyngmo
            Nov 22 at 15:20






          • 1




            I added a xxx::list replacement for std::list that hopefully should work as a container for both copyable and non-copyable objects. I''m terrible with templates though so be aware ...
            – Ted Lyngmo
            Nov 22 at 17:47
















          2














          As @j6t pointed out, it seems it can't be done. A vector with a std::list with non-copyable elements can not be expanded according to the standard (...). If it was my private project I'd actually consider something like this:



          #include <iostream>
          #include <vector>
          #include <list>

          namespace xxx {
          // <flame_bait>
          template<class T, class Enable = void>
          struct list : std::list<T> {
          list() : std::list<T>() {}
          list(list&&) = default;
          list& operator=(list&&) = default;
          list(const list&) = delete;
          list& operator=(const list&) = delete;
          };

          template<class T>
          struct list<T, typename std::enable_if<std::is_copy_constructible<T>::value>::type> : std::list<T> {};
          // </flame_bait>
          }

          struct NonCopyable
          {
          int m_id;
          NonCopyable(int id = 0) : m_id(id) {}
          NonCopyable(const NonCopyable&) = delete;
          NonCopyable& operator = (const NonCopyable&) = delete;
          NonCopyable(NonCopyable&&) noexcept = default;
          NonCopyable& operator = (NonCopyable&&) noexcept = default;
          ~NonCopyable() = default;
          friend std::ostream& operator<<(std::ostream&, const NonCopyable&);
          };

          std::ostream& operator<<(std::ostream& os, const NonCopyable& nc) {
          os << "I am not a free man, I am number " << nc.m_id;
          return os;
          }

          int main() {
          std::vector<xxx::list<NonCopyable>> v;
          v.resize(4); // now working

          int id = 0;
          for (auto& l : v) {
          l.emplace_back(++id); // emplace_back one NonCopyable per list
          }

          xxx::list<NonCopyable> li; // Create a separate list
          li.emplace_back(++id); // create one...
          v.emplace_back(std::move(li)); // and move list to vector is now working

          for (auto& l : v) {
          for (auto& nc : l) {
          std::cout << nc << "n";
          }
          }
          }


          Expected output:



          I am not a free man, I am number 1
          I am not a free man, I am number 2
          I am not a free man, I am number 3
          I am not a free man, I am number 4
          I am not a free man, I am number 5





          share|improve this answer























          • Seems I missed the part where v.resize(4); fails. What's the error message from that line?
            – Ted Lyngmo
            Nov 22 at 13:59






          • 1




            error C2280: 'NonCopyable::NonCopyable(const NonCopyable &)': attempting to reference a deleted function. I've added the full error output for that to the post.
            – Uri Zarfaty
            Nov 22 at 14:11






          • 1




            Great! How odd though ... :-) I'll give it a try in VS when I get home.
            – Ted Lyngmo
            Nov 22 at 14:14












          • Just to make it worse: v.reserve(4); gives the same error.
            – Ted Lyngmo
            Nov 22 at 15:20






          • 1




            I added a xxx::list replacement for std::list that hopefully should work as a container for both copyable and non-copyable objects. I''m terrible with templates though so be aware ...
            – Ted Lyngmo
            Nov 22 at 17:47














          2












          2








          2






          As @j6t pointed out, it seems it can't be done. A vector with a std::list with non-copyable elements can not be expanded according to the standard (...). If it was my private project I'd actually consider something like this:



          #include <iostream>
          #include <vector>
          #include <list>

          namespace xxx {
          // <flame_bait>
          template<class T, class Enable = void>
          struct list : std::list<T> {
          list() : std::list<T>() {}
          list(list&&) = default;
          list& operator=(list&&) = default;
          list(const list&) = delete;
          list& operator=(const list&) = delete;
          };

          template<class T>
          struct list<T, typename std::enable_if<std::is_copy_constructible<T>::value>::type> : std::list<T> {};
          // </flame_bait>
          }

          struct NonCopyable
          {
          int m_id;
          NonCopyable(int id = 0) : m_id(id) {}
          NonCopyable(const NonCopyable&) = delete;
          NonCopyable& operator = (const NonCopyable&) = delete;
          NonCopyable(NonCopyable&&) noexcept = default;
          NonCopyable& operator = (NonCopyable&&) noexcept = default;
          ~NonCopyable() = default;
          friend std::ostream& operator<<(std::ostream&, const NonCopyable&);
          };

          std::ostream& operator<<(std::ostream& os, const NonCopyable& nc) {
          os << "I am not a free man, I am number " << nc.m_id;
          return os;
          }

          int main() {
          std::vector<xxx::list<NonCopyable>> v;
          v.resize(4); // now working

          int id = 0;
          for (auto& l : v) {
          l.emplace_back(++id); // emplace_back one NonCopyable per list
          }

          xxx::list<NonCopyable> li; // Create a separate list
          li.emplace_back(++id); // create one...
          v.emplace_back(std::move(li)); // and move list to vector is now working

          for (auto& l : v) {
          for (auto& nc : l) {
          std::cout << nc << "n";
          }
          }
          }


          Expected output:



          I am not a free man, I am number 1
          I am not a free man, I am number 2
          I am not a free man, I am number 3
          I am not a free man, I am number 4
          I am not a free man, I am number 5





          share|improve this answer














          As @j6t pointed out, it seems it can't be done. A vector with a std::list with non-copyable elements can not be expanded according to the standard (...). If it was my private project I'd actually consider something like this:



          #include <iostream>
          #include <vector>
          #include <list>

          namespace xxx {
          // <flame_bait>
          template<class T, class Enable = void>
          struct list : std::list<T> {
          list() : std::list<T>() {}
          list(list&&) = default;
          list& operator=(list&&) = default;
          list(const list&) = delete;
          list& operator=(const list&) = delete;
          };

          template<class T>
          struct list<T, typename std::enable_if<std::is_copy_constructible<T>::value>::type> : std::list<T> {};
          // </flame_bait>
          }

          struct NonCopyable
          {
          int m_id;
          NonCopyable(int id = 0) : m_id(id) {}
          NonCopyable(const NonCopyable&) = delete;
          NonCopyable& operator = (const NonCopyable&) = delete;
          NonCopyable(NonCopyable&&) noexcept = default;
          NonCopyable& operator = (NonCopyable&&) noexcept = default;
          ~NonCopyable() = default;
          friend std::ostream& operator<<(std::ostream&, const NonCopyable&);
          };

          std::ostream& operator<<(std::ostream& os, const NonCopyable& nc) {
          os << "I am not a free man, I am number " << nc.m_id;
          return os;
          }

          int main() {
          std::vector<xxx::list<NonCopyable>> v;
          v.resize(4); // now working

          int id = 0;
          for (auto& l : v) {
          l.emplace_back(++id); // emplace_back one NonCopyable per list
          }

          xxx::list<NonCopyable> li; // Create a separate list
          li.emplace_back(++id); // create one...
          v.emplace_back(std::move(li)); // and move list to vector is now working

          for (auto& l : v) {
          for (auto& nc : l) {
          std::cout << nc << "n";
          }
          }
          }


          Expected output:



          I am not a free man, I am number 1
          I am not a free man, I am number 2
          I am not a free man, I am number 3
          I am not a free man, I am number 4
          I am not a free man, I am number 5






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 22 at 17:39

























          answered Nov 22 at 13:53









          Ted Lyngmo

          1,927315




          1,927315












          • Seems I missed the part where v.resize(4); fails. What's the error message from that line?
            – Ted Lyngmo
            Nov 22 at 13:59






          • 1




            error C2280: 'NonCopyable::NonCopyable(const NonCopyable &)': attempting to reference a deleted function. I've added the full error output for that to the post.
            – Uri Zarfaty
            Nov 22 at 14:11






          • 1




            Great! How odd though ... :-) I'll give it a try in VS when I get home.
            – Ted Lyngmo
            Nov 22 at 14:14












          • Just to make it worse: v.reserve(4); gives the same error.
            – Ted Lyngmo
            Nov 22 at 15:20






          • 1




            I added a xxx::list replacement for std::list that hopefully should work as a container for both copyable and non-copyable objects. I''m terrible with templates though so be aware ...
            – Ted Lyngmo
            Nov 22 at 17:47


















          • Seems I missed the part where v.resize(4); fails. What's the error message from that line?
            – Ted Lyngmo
            Nov 22 at 13:59






          • 1




            error C2280: 'NonCopyable::NonCopyable(const NonCopyable &)': attempting to reference a deleted function. I've added the full error output for that to the post.
            – Uri Zarfaty
            Nov 22 at 14:11






          • 1




            Great! How odd though ... :-) I'll give it a try in VS when I get home.
            – Ted Lyngmo
            Nov 22 at 14:14












          • Just to make it worse: v.reserve(4); gives the same error.
            – Ted Lyngmo
            Nov 22 at 15:20






          • 1




            I added a xxx::list replacement for std::list that hopefully should work as a container for both copyable and non-copyable objects. I''m terrible with templates though so be aware ...
            – Ted Lyngmo
            Nov 22 at 17:47
















          Seems I missed the part where v.resize(4); fails. What's the error message from that line?
          – Ted Lyngmo
          Nov 22 at 13:59




          Seems I missed the part where v.resize(4); fails. What's the error message from that line?
          – Ted Lyngmo
          Nov 22 at 13:59




          1




          1




          error C2280: 'NonCopyable::NonCopyable(const NonCopyable &)': attempting to reference a deleted function. I've added the full error output for that to the post.
          – Uri Zarfaty
          Nov 22 at 14:11




          error C2280: 'NonCopyable::NonCopyable(const NonCopyable &)': attempting to reference a deleted function. I've added the full error output for that to the post.
          – Uri Zarfaty
          Nov 22 at 14:11




          1




          1




          Great! How odd though ... :-) I'll give it a try in VS when I get home.
          – Ted Lyngmo
          Nov 22 at 14:14






          Great! How odd though ... :-) I'll give it a try in VS when I get home.
          – Ted Lyngmo
          Nov 22 at 14:14














          Just to make it worse: v.reserve(4); gives the same error.
          – Ted Lyngmo
          Nov 22 at 15:20




          Just to make it worse: v.reserve(4); gives the same error.
          – Ted Lyngmo
          Nov 22 at 15:20




          1




          1




          I added a xxx::list replacement for std::list that hopefully should work as a container for both copyable and non-copyable objects. I''m terrible with templates though so be aware ...
          – Ted Lyngmo
          Nov 22 at 17:47




          I added a xxx::list replacement for std::list that hopefully should work as a container for both copyable and non-copyable objects. I''m terrible with templates though so be aware ...
          – Ted Lyngmo
          Nov 22 at 17:47


















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.





          Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


          Please pay close attention to the following guidance:


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53432012%2fnon-copyable-elements-in-a-stdvector-of-stdlists%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Berounka

          Sphinx de Gizeh

          Different font size/position of beamer's navigation symbols template's content depending on regular/plain...