EASTL: Cannot move assign a eastl::vector>

#include <memory>
#include <vector>
#include <EASTL/vector.h>

int main(int, char**) {

  // Works                                                                                                                         
  std::vector<std::unique_ptr<int>> stdv1;
  std::vector<std::unique_ptr<int>> stdv2;
  stdv2 = std::move(stdv1);

  // Doesn't work                                                                                                                  
  eastl::vector<std::unique_ptr<int>> v1;
  eastl::vector<std::unique_ptr<int>> v2;
  v2 = std::move(v1);

}


The output on os x clang 3.9:


clang++ -std=c++14 eastl-vector-move.cpp 
In file included from eastl-vector-move.cpp:3:
In file included from /usr/local/include/EASTL/vector.h:42:
/usr/local/include/EASTL/memory.h:605:34: error: call to implicitly-deleted copy constructor of 'value_type' (aka
      'std::__1::unique_ptr<int, std::__1::default_delete<int> >')
                                        ::new((void*)&*currentDest) value_type(*first);
                                                                    ^          ~~~~~~
/usr/local/include/EASTL/memory.h:705:52: note: in instantiation of function template specialization
      'eastl::Internal::uninitialized_copy_impl<eastl::generic_iterator<std::__1::unique_ptr<int, std::__1::default_delete<int> >
      *, void>, eastl::generic_iterator<std::__1::unique_ptr<int, std::__1::default_delete<int> > *, void> >' requested here
                const generic_iterator<Result, void> i(Internal::uninitialized_copy_impl(eastl::generic_iterator<First, voi...
                                                                 ^
/usr/local/include/EASTL/vector.h:578:18: note: in instantiation of function template specialization
      'eastl::uninitialized_copy_ptr<std::__1::unique_ptr<int, std::__1::default_delete<int> > *, std::__1::unique_ptr<int,
      std::__1::default_delete<int> > *, std::__1::unique_ptr<int, std::__1::default_delete<int> > *>' requested here
                mpEnd = eastl::uninitialized_copy_ptr(x.mpBegin, x.mpEnd, mpBegin);
                               ^
/usr/local/include/EASTL/vector.h:1733:13: note: in instantiation of member function 'eastl::vector<std::__1::unique_ptr<int,
      std::__1::default_delete<int> >, eastl::allocator>::vector' requested here
                this_type temp(*this);  // This is the simplest way to accomplish this, 
                          ^
/usr/local/include/EASTL/vector.h:685:5: note: in instantiation of member function 'eastl::vector<std::__1::unique_ptr<int,
      std::__1::default_delete<int> >, eastl::allocator>::DoClearCapacity' requested here
                                DoClearCapacity(); // To consider: Are we really required to clear here? x is going away so...
                                ^
eastl-vector-move.cpp:8:6: note: in instantiation of member function 'eastl::vector<std::__1::unique_ptr<int,
      std::__1::default_delete<int> >, eastl::allocator>::operator=' requested here
  v2 = std::move(v1);
     ^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/memory:2600:31: note: copy constructor is implicitly deleted because
      'unique_ptr<int, std::__1::default_delete<int> >' has a user-declared move constructor
    _LIBCPP_INLINE_VISIBILITY unique_ptr(unique_ptr&& __u) _NOEXCEPT
                              ^
In file included from eastl-vector-move.cpp:3:
In file included from /usr/local/include/EASTL/vector.h:40:
In file included from /usr/local/include/EASTL/algorithm.h:237:
/usr/local/include/EASTL/internal/copy_help.h:73:13: error: object of type 'std::__1::unique_ptr<int, std::__1::default_delete<int>
      >' cannot be assigned because its copy assignment operator is implicitly deleted
                                *result = *first;
                                        ^
/usr/local/include/EASTL/internal/copy_help.h:135:67: note: in instantiation of function template specialization
      'eastl::move_and_copy_helper<eastl::random_access_iterator_tag, false, false>::move_or_copy<const std::__1::unique_ptr<int,
      std::__1::default_delete<int> > *, std::__1::unique_ptr<int, std::__1::default_delete<int> > *>' requested here
                return eastl::move_and_copy_helper<IIC, isMove, canBeMemmoved>::move_or_copy(first, last, result); // Need ...
                                                                                ^
/usr/local/include/EASTL/internal/copy_help.h:143:32: note: in instantiation of function template specialization
      'eastl::move_and_copy_chooser<false, const std::__1::unique_ptr<int, std::__1::default_delete<int> > *,
      std::__1::unique_ptr<int, std::__1::default_delete<int> > *>' requested here
                return OutputIterator(eastl::move_and_copy_chooser<isMove>(eastl::unwrap_iterator(first), eastl::unwrap_ite...
                                             ^
/usr/local/include/EASTL/internal/copy_help.h:193:17: note: in instantiation of function template specialization
      'eastl::move_and_copy_unwrapper<false, const std::__1::unique_ptr<int, std::__1::default_delete<int> > *,
      std::__1::unique_ptr<int, std::__1::default_delete<int> > *>' requested here
                return eastl::move_and_copy_unwrapper<isMove>(eastl::unwrap_iterator(first), eastl::unwrap_iterator(last), result);
                              ^
/usr/local/include/EASTL/vector.h:1543:35: note: in instantiation of function template specialization 'eastl::copy<const
      std::__1::unique_ptr<int, std::__1::default_delete<int> > *, std::__1::unique_ptr<int, std::__1::default_delete<int> > *>'
      requested here
                        pointer const pNewEnd = eastl::copy(first, last, mpBegin); // Since we are copying to mpBegin, we d...
                                                       ^
/usr/local/include/EASTL/vector.h:1480:3: note: in instantiation of function template specialization
      'eastl::vector<std::__1::unique_ptr<int, std::__1::default_delete<int> >, eastl::allocator>::DoAssignFromIterator<const
      std::__1::unique_ptr<int, std::__1::default_delete<int> > *, false>' requested here
                DoAssignFromIterator<InputIterator, bMove>(first, last, IC());
                ^
/usr/local/include/EASTL/vector.h:660:4: note: in instantiation of function template specialization
      'eastl::vector<std::__1::unique_ptr<int, std::__1::default_delete<int> >, eastl::allocator>::DoAssign<const
      std::__1::unique_ptr<int, std::__1::default_delete<int> > *, false>' requested here
                        DoAssign<const_iterator, false>(x.begin(), x.end(), eastl::false_type());
                        ^
/usr/local/include/EASTL/vector.h:1393:10: note: in instantiation of member function 'eastl::vector<std::__1::unique_ptr<int,
      std::__1::default_delete<int> >, eastl::allocator>::operator=' requested here
                        *this = x;                   // itself call this member swap function.
                              ^
/usr/local/include/EASTL/vector.h:686:5: note: in instantiation of member function 'eastl::vector<std::__1::unique_ptr<int,
      std::__1::default_delete<int> >, eastl::allocator>::swap' requested here
                                swap(x);           // member swap handles the case that x has a different allocator than ou...
                                ^
eastl-vector-move.cpp:8:6: note: in instantiation of member function 'eastl::vector<std::__1::unique_ptr<int,
      std::__1::default_delete<int> >, eastl::allocator>::operator=' requested here
  v2 = std::move(v1);
     ^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/memory:2600:31: note: copy assignment operator is implicitly deleted
      because 'unique_ptr<int, std::__1::default_delete<int> >' has a user-declared move constructor
    _LIBCPP_INLINE_VISIBILITY unique_ptr(unique_ptr&& __u) _NOEXCEPT
                              ^
In file included from eastl-vector-move.cpp:3:
In file included from /usr/local/include/EASTL/vector.h:42:
/usr/local/include/EASTL/memory.h:605:34: error: call to implicitly-deleted copy constructor of 'value_type' (aka
      'std::__1::unique_ptr<int, std::__1::default_delete<int> >')
                                        ::new((void*)&*currentDest) value_type(*first);
                                                                    ^          ~~~~~~
/usr/local/include/EASTL/memory.h:705:52: note: in instantiation of function template specialization
      'eastl::Internal::uninitialized_copy_impl<eastl::generic_iterator<const std::__1::unique_ptr<int,
      std::__1::default_delete<int> > *, void>, eastl::generic_iterator<std::__1::unique_ptr<int, std::__1::default_delete<int> >
      *, void> >' requested here
                const generic_iterator<Result, void> i(Internal::uninitialized_copy_impl(eastl::generic_iterator<First, voi...
                                                                 ^
/usr/local/include/EASTL/vector.h:1551:19: note: in instantiation of function template specialization
      'eastl::uninitialized_copy_ptr<const std::__1::unique_ptr<int, std::__1::default_delete<int> > *, const
      std::__1::unique_ptr<int, std::__1::default_delete<int> > *, std::__1::unique_ptr<int, std::__1::default_delete<int> > *>'
      requested here
                        mpEnd = eastl::uninitialized_copy_ptr(position, last, mpEnd);
                                       ^
/usr/local/include/EASTL/vector.h:1480:3: note: in instantiation of function template specialization
      'eastl::vector<std::__1::unique_ptr<int, std::__1::default_delete<int> >, eastl::allocator>::DoAssignFromIterator<const
      std::__1::unique_ptr<int, std::__1::default_delete<int> > *, false>' requested here
                DoAssignFromIterator<InputIterator, bMove>(first, last, IC());
                ^
/usr/local/include/EASTL/vector.h:660:4: note: in instantiation of function template specialization
      'eastl::vector<std::__1::unique_ptr<int, std::__1::default_delete<int> >, eastl::allocator>::DoAssign<const
      std::__1::unique_ptr<int, std::__1::default_delete<int> > *, false>' requested here
                        DoAssign<const_iterator, false>(x.begin(), x.end(), eastl::false_type());
                        ^
/usr/local/include/EASTL/vector.h:1393:10: note: in instantiation of member function 'eastl::vector<std::__1::unique_ptr<int,
      std::__1::default_delete<int> >, eastl::allocator>::operator=' requested here
                        *this = x;                   // itself call this member swap function.
                              ^
/usr/local/include/EASTL/vector.h:686:5: note: in instantiation of member function 'eastl::vector<std::__1::unique_ptr<int,
      std::__1::default_delete<int> >, eastl::allocator>::swap' requested here
                                swap(x);           // member swap handles the case that x has a different allocator than ou...
                                ^
eastl-vector-move.cpp:8:6: note: in instantiation of member function 'eastl::vector<std::__1::unique_ptr<int,
      std::__1::default_delete<int> >, eastl::allocator>::operator=' requested here
  v2 = std::move(v1);
     ^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/memory:2600:31: note: copy constructor is implicitly deleted because
      'unique_ptr<int, std::__1::default_delete<int> >' has a user-declared move constructor
    _LIBCPP_INLINE_VISIBILITY unique_ptr(unique_ptr&& __u) _NOEXCEPT
                              ^
3 errors generated.

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Comments: 45 (11 by maintainers)

Most upvoted comments

sounds good.

I tried applying your work around using Microsoft Visual C++ 2015, but your sample still fails for me:

1>------ Build started: Project: ToolingTestCore, Configuration: Debug Win32 ------
1>  heap_thrash.cpp
1>c:\git\biodrome\eastl\include\eastl\memory.h(595): error C2280: 'std::unique_ptr<int,std::default_delete<_Ty>>::unique_ptr(const std::unique_ptr<_Ty,std::default_delete<_Ty>> &)': attempting to reference a deleted function
1>          with
1>          [
1>              _Ty=int
1>          ]
1>  c:\program files (x86)\microsoft visual studio 14.0\vc\include\memory(1435): note: see declaration of 'std::unique_ptr<int,std::default_delete<_Ty>>::unique_ptr'
1>          with
1>          [
1>              _Ty=int
1>          ]
1>  c:\git\biodrome\eastl\include\eastl\memory.h(708): note: see reference to function template instantiation 'ForwardIterator eastl::Internal::uninitialized_copy_impl<eastl::generic_iterator<Result,void>,eastl::generic_iterator<Result,void>>(InputIterator,InputIterator,ForwardIterator,eastl::false_type)' being compiled
1>          with
1>          [
1>              ForwardIterator=eastl::generic_iterator<std::unique_ptr<int,std::default_delete<int>> *,void>,
1>              Result=std::unique_ptr<int,std::default_delete<int>> *,
1>              InputIterator=eastl::generic_iterator<std::unique_ptr<int,std::default_delete<int>> *,void>
1>          ]
1>  c:\git\biodrome\eastl\include\eastl\vector.h(578): note: see reference to function template instantiation 'Result eastl::uninitialized_copy_ptr<T*,T*,T*>(First,Last,Result)' being compiled
1>          with
1>          [
1>              Result=std::unique_ptr<int,std::default_delete<int>> *,
1>              T=std::unique_ptr<int,std::default_delete<int>>,
1>              First=std::unique_ptr<int,std::default_delete<int>> *,
1>              Last=std::unique_ptr<int,std::default_delete<int>> *
1>          ]
1>  c:\git\biodrome\eastl\include\eastl\vector.h(576): note: while compiling class template member function 'eastl::vector<std::unique_ptr<int,std::default_delete<_Ty>>,eastl::allocator>::vector(const eastl::vector<std::unique_ptr<_Ty,std::default_delete<_Ty>>,eastl::allocator> &)'
1>          with
1>          [
1>              _Ty=int
1>          ]
1>  c:\git\biodrome\eastl\include\eastl\vector.h(1748): note: see reference to function template instantiation 'eastl::vector<std::unique_ptr<int,std::default_delete<_Ty>>,eastl::allocator>::vector(const eastl::vector<std::unique_ptr<_Ty,std::default_delete<_Ty>>,eastl::allocator> &)' being compiled
1>          with
1>          [
1>              _Ty=int
1>          ]
1>  c:\git\biodrome\eastl\include\eastl\vector.h(1399): note: while compiling class template member function 'void eastl::vector<std::unique_ptr<int,std::default_delete<_Ty>>,eastl::allocator>::swap(eastl::vector<std::unique_ptr<_Ty,std::default_delete<_Ty>>,eastl::allocator> &)'
1>          with
1>          [
1>              _Ty=int
1>          ]
1>  c:\git\biodrome\eastl\include\eastl\vector.h(686): note: see reference to function template instantiation 'void eastl::vector<std::unique_ptr<int,std::default_delete<_Ty>>,eastl::allocator>::swap(eastl::vector<std::unique_ptr<_Ty,std::default_delete<_Ty>>,eastl::allocator> &)' being compiled
1>          with
1>          [
1>              _Ty=int
1>          ]
1>  c:\git\biodrome\eastl\include\eastl\vector.h(542): note: while compiling class template member function 'eastl::vector<std::unique_ptr<int,std::default_delete<_Ty>>,eastl::allocator>::vector(void)'
1>          with
1>          [
1>              _Ty=int
1>          ]
1>  c:\git\biodrome\sandbox\toolingtest\toolingtestcore\heap_thrash.cpp(116): note: see reference to function template instantiation 'eastl::vector<std::unique_ptr<int,std::default_delete<_Ty>>,eastl::allocator>::vector(void)' being compiled
1>          with
1>          [
1>              _Ty=int
1>          ]
1>  c:\git\biodrome\sandbox\toolingtest\toolingtestcore\heap_thrash.cpp(116): note: see reference to class template instantiation 'eastl::vector<std::unique_ptr<int,std::default_delete<_Ty>>,eastl::allocator>' being compiled
1>          with
1>          [
1>              _Ty=int
1>          ]
========== Build: 0 succeeded, 1 failed, 2 up-to-date, 0 skipped ==========

I found this bug report investigating a slightly different, but probably related issue:

std::vector<std::unique_ptr<int>> test_func_std() { return{}; }
eastl::vector<eastl::unique_ptr<int>> test_func_eastl() { return{}; }

int main(int, char**) 
{
  // Works                                                                                                                         
  std::vector<std::unique_ptr<int>> std_res;
  std_res = test_func_std();

  // Doesn't work                                                                                                                  
  eastl::vector<eastl::unique_ptr<int>> eastl_res;
  eastl_res = test_func_eastl();
}

The error in this case looks like this:

1>------ Build started: Project: ToolingTestCore, Configuration: Debug Win32 ------
1>  heap_thrash.cpp
1>c:\git\biodrome\eastl\include\eastl\memory.h(595): error C2248: 'eastl::unique_ptr<int,eastl::default_delete<T>>::unique_ptr': cannot access protected member declared in class 'eastl::unique_ptr<int,eastl::default_delete<T>>'
1>          with
1>          [
1>              T=int
1>          ]
1>  c:\git\biodrome\eastl\include\eastl\unique_ptr.h(339): note: see declaration of 'eastl::unique_ptr<int,eastl::default_delete<T>>::unique_ptr'
1>          with
1>          [
1>              T=int
1>          ]
1>  c:\git\biodrome\sandbox\toolingtest\toolingtestcore\heap_thrash.cpp(73): note: see declaration of 'eastl::unique_ptr<int,eastl::default_delete<T>>'
1>          with
1>          [
1>              T=int
1>          ]
1>  c:\git\biodrome\eastl\include\eastl\memory.h(708): note: see reference to function template instantiation 'ForwardIterator eastl::Internal::uninitialized_copy_impl<eastl::generic_iterator<Result,void>,eastl::generic_iterator<Result,void>>(InputIterator,InputIterator,ForwardIterator,eastl::false_type)' being compiled
1>          with
1>          [
1>              ForwardIterator=eastl::generic_iterator<eastl::unique_ptr<int,eastl::default_delete<int>> *,void>,
1>              Result=eastl::unique_ptr<int,eastl::default_delete<int>> *,
1>              InputIterator=eastl::generic_iterator<eastl::unique_ptr<int,eastl::default_delete<int>> *,void>
1>          ]
1>  c:\git\biodrome\eastl\include\eastl\vector.h(578): note: see reference to function template instantiation 'Result eastl::uninitialized_copy_ptr<T*,T*,T*>(First,Last,Result)' being compiled
1>          with
1>          [
1>              Result=eastl::unique_ptr<int,eastl::default_delete<int>> *,
1>              T=eastl::unique_ptr<int,eastl::default_delete<int>>,
1>              First=eastl::unique_ptr<int,eastl::default_delete<int>> *,
1>              Last=eastl::unique_ptr<int,eastl::default_delete<int>> *
1>          ]
1>  c:\git\biodrome\eastl\include\eastl\vector.h(576): note: while compiling class template member function 'eastl::vector<eastl::unique_ptr<int,eastl::default_delete<T>>,eastl::allocator>::vector(const eastl::vector<eastl::unique_ptr<T,eastl::default_delete<T>>,eastl::allocator> &)'
1>          with
1>          [
1>              T=int
1>          ]
1>  c:\git\biodrome\eastl\include\eastl\vector.h(1748): note: see reference to function template instantiation 'eastl::vector<eastl::unique_ptr<int,eastl::default_delete<T>>,eastl::allocator>::vector(const eastl::vector<eastl::unique_ptr<T,eastl::default_delete<T>>,eastl::allocator> &)' being compiled
1>          with
1>          [
1>              T=int
1>          ]
1>  c:\git\biodrome\eastl\include\eastl\vector.h(1399): note: while compiling class template member function 'void eastl::vector<eastl::unique_ptr<int,eastl::default_delete<T>>,eastl::allocator>::swap(eastl::vector<eastl::unique_ptr<T,eastl::default_delete<T>>,eastl::allocator> &)'
1>          with
1>          [
1>              T=int
1>          ]
1>  c:\git\biodrome\eastl\include\eastl\vector.h(686): note: see reference to function template instantiation 'void eastl::vector<eastl::unique_ptr<int,eastl::default_delete<T>>,eastl::allocator>::swap(eastl::vector<eastl::unique_ptr<T,eastl::default_delete<T>>,eastl::allocator> &)' being compiled
1>          with
1>          [
1>              T=int
1>          ]
1>  c:\git\biodrome\eastl\include\eastl\vector.h(542): note: while compiling class template member function 'eastl::vector<eastl::unique_ptr<int,eastl::default_delete<T>>,eastl::allocator>::vector(void)'
1>          with
1>          [
1>              T=int
1>          ]
1>  c:\git\biodrome\sandbox\toolingtest\toolingtestcore\heap_thrash.cpp(73): note: see reference to function template instantiation 'eastl::vector<eastl::unique_ptr<int,eastl::default_delete<T>>,eastl::allocator>::vector(void)' being compiled
1>          with
1>          [
1>              T=int
1>          ]
1>  c:\git\biodrome\sandbox\toolingtest\toolingtestcore\heap_thrash.cpp(73): note: see reference to class template instantiation 'eastl::vector<eastl::unique_ptr<int,eastl::default_delete<T>>,eastl::allocator>' being compiled
1>          with
1>          [
1>              T=int
1>          ]
========== Build: 0 succeeded, 1 failed, 2 up-to-date, 0 skipped ==========

Unfortunately, I’m still more of a library user than writer, so I don’t know how I’d solve this.