Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error after trying to get unique_ptr element from vector

I read about how to insert a unique_ptr<T> into a vector<unique_ptr<T>>: Why can I not push_back a unique_ptr into a vector?

But how do I get a element back? I made an example:

#include <memory>
#include <vector>

class A {
  public:
    A(int x, int y){
      x_ = x;
      y_ = y;
    }
  private:
    int x_;
    int y_;
};


int main(){
  std::vector<std::unique_ptr<A>> vec_a;
  std::unique_ptr<A> tmp_a = std::unique_ptr<A>(new A(13,32));

  vec_a.push_back(std::move(tmp_a));

  vec_a.push_back(std::unique_ptr<A>(new A(3,2)));

  // error
  std::unique_ptr<A> a = vec_a.at(0);
}

I'm getting this error message:

main.cc: In function ‘int main()’:
main.cc:24:36: error: use of deleted function 
      ‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) 
      [with _Tp = A; _Dp = std::default_delete<A>]’
   std::unique_ptr<A> a = vec_a.at(0);
                                    ^
In file included from /usr/include/c++/4.8/memory:81:0,
                 from main.cc:1:
/usr/include/c++/4.8/bits/unique_ptr.h:273:7: error: declared here
       unique_ptr(const unique_ptr&) = delete;
       ^

What I'm doing wrong? How should I do it? And why does this not work?

like image 215
Victor Avatar asked Dec 25 '13 13:12

Victor


2 Answers

unique_ptr cannot be copied or assigned. It needs to be move copied or move assigned. You can achieve this by use of std::move:

std::unique_ptr<A> a = std::move(vec_a.at(0));

The call to std::move essentially allows you to treat the RHS as an rvalue, which can then be used in unique_ptr'a move copy constructor.

Note that after this, you will have to be careful with the first element of vec_a.

If you don't want to take ownership of the pointer away from the vector, simply access the managed pointer directly:

A* a = vec_a.at(0).get();

You have to be careful not to use a after the object it points to has ceased to exist.

like image 167
juanchopanza Avatar answered Nov 17 '22 20:11

juanchopanza


It's a unique_ptr, and you're attempting to make a copy. One way to fix is to get the raw pointer instead:

A* a = vec_a.at(0).get();

Keep in mind the vector will still own the pointer, and will still delete it when the vector goes out of scope.

like image 45
Mark Tolonen Avatar answered Nov 17 '22 22:11

Mark Tolonen