mercredi 27 avril 2022

Moving all Elements in a std::vector not working as expected

I'm trying to move the whole vector to another variable. The following code block does not compile. I thought that the call to std::move would force to use the Move-Constructor. Instead it seems like std::vector is using the Copy-Constructor that is deleted.

What's wrong here? How can I move all elements without copying them?

#include <vector>

class TheClass {
public:
  TheClass(const TheClass&) = delete;
  TheClass(TheClass&&) = default;
};

void fun2(const std::vector<TheClass> data) {
  std::vector<TheClass> a = std::move(data);
  a.size();
}

leads to:

clang++ -o /cplayground/cplayground /cplayground/code.cpp -I/cplayground/include -L/cplayground/lib -std=c++20 -O0 -Wall -no-pie -lm -pthread
In file included from /cplayground/code.cpp:1:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/vector:66:
/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/stl_uninitialized.h:137:7: error: static_assert failed due to requirement 'is_constructible<TheClass, const TheClass &>::value' "result type must be constructible from value type of input range"
      static_assert(is_constructible<_ValueType2, decltype(*__first)>::value,
      ^             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/stl_uninitialized.h:325:19: note: in instantiation of function template specialization 'std::uninitialized_copy<__gnu_cxx::__normal_iterator<const TheClass *, std::vector<TheClass, std::allocator<TheClass> > >, TheClass *>' requested here
    { return std::uninitialized_copy(__first, __last, __result); }
                  ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/stl_vector.h:558:9: note: in instantiation of function template specialization 'std::__uninitialized_copy_a<__gnu_cxx::__normal_iterator<const TheClass *, std::vector<TheClass, std::allocator<TheClass> > >, TheClass *, TheClass>' requested here
          std::__uninitialized_copy_a(__x.begin(), __x.end(),
               ^
/cplayground/code.cpp:10:29: note: in instantiation of member function 'std::vector<TheClass, std::allocator<TheClass> >::vector' requested here
  std::vector<TheClass> a = std::move(data);
                            ^
In file included from /cplayground/code.cpp:1:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/vector:62:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/stl_algo.h:62:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/stl_tempbuf.h:60:
/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/stl_construct.h:109:38: error: call to deleted constructor of 'TheClass'
    { ::new(static_cast<void*>(__p)) _Tp(std::forward<_Args>(__args)...); }
                                     ^   ~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/stl_uninitialized.h:91:8: note: in instantiation of function template specialization 'std::_Construct<TheClass, const TheClass &>' requested here
                std::_Construct(std::__addressof(*__cur), *__first);
                     ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/stl_uninitialized.h:150:2: note: in instantiation of function template specialization 'std::__uninitialized_copy<false>::__uninit_copy<__gnu_cxx::__normal_iterator<const TheClass *, std::vector<TheClass, std::allocator<TheClass> > >, TheClass *>' requested here
        __uninit_copy(__first, __last, __result);
        ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/stl_uninitialized.h:325:19: note: in instantiation of function template specialization 'std::uninitialized_copy<__gnu_cxx::__normal_iterator<const TheClass *, std::vector<TheClass, std::allocator<TheClass> > >, TheClass *>' requested here
    { return std::uninitialized_copy(__first, __last, __result); }
                  ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/stl_vector.h:558:9: note: in instantiation of function template specialization 'std::__uninitialized_copy_a<__gnu_cxx::__normal_iterator<const TheClass *, std::vector<TheClass, std::allocator<TheClass> > >, TheClass *, TheClass>' requested here
          std::__uninitialized_copy_a(__x.begin(), __x.end(),
               ^
/cplayground/code.cpp:10:29: note: in instantiation of member function 'std::vector<TheClass, std::allocator<TheClass> >::vector' requested here
  std::vector<TheClass> a = std::move(data);
                            ^
/cplayground/code.cpp:5:3: note: 'TheClass' has been explicitly marked deleted here
  TheClass(const TheClass&) = delete;
  ^
2 errors generated.

Aucun commentaire:

Enregistrer un commentaire