Jim
Jim

Reputation: 55

Accessing unique_ptrs in std vector - must provide copy constructor?

I've created a std vector and pushed back a bunch of objects onto it using the std move, such as:

vector<unique_ptr<Foo> > myVec;
unique_ptr<Foo> a = make_unique<Foo>();
unique_ptr<Foo> b = make_unique<Foo>();
myVec.push_back(move(a));
myVec.push_back(move(b));

So far, so good.

Later on, I pass a reference of myVec to a function and try to access the data in the vector using the []-operators.

void someFunc(vector<unique_ptr<Foo> > &myVec)
{
    Foo* anObj = myVec[0];
}

After some reading, my guess is that this approach is not going to work, because the std vector will try and make a copy and unless I provide a copyconstructor on Foo that avoids actually making a copy it wont ever work. Am I correct? I think I saw some posts about using iterators, but I'd rather not if I dont have to.

EDIT1:

I did manage to work around it by the following (using iterator and then get to get the raw pointer)

void someFunc(vector<unique_ptr<Foo> > &myVec)
{
    int offset = 0; // Or some other offset into the vector
    auto it = myVec.begin() + offset;
    Foo* anObj = it.get();
    // ... Do something using anObj here...
}

I would think this is the way to go, as long as you dont foolishly try to retain the anObj and then free it manually somewhere. I could of course transfer ownership temporarly until Im done with it and then return the ownership but it feels like such a hassle. Any thoughts on the above approach?

Thanks in advance, /Jimmie

Upvotes: 1

Views: 88

Answers (2)

OdedR
OdedR

Reputation: 123

C++ not decide for you if using copy or reference assignment.

You should handle it by your self.

  • If you declare new variable and using = operator in the declaration line like int y = x; you are using copy constructor.
  • If you declare a variable with & before it, like int & y = x; you are taking the reference of x and store it in y.

In your example, you have 2 problems:

  1. You are trying to assign unique_ptr<Foo> to Foo* which is incorrect.
  2. You want to have the unique_ptr<Foo> reference so you should declare unique_ptr<Foo> reference like this: unique_ptr<Foo> & ref = myVec[0];

Upvotes: 0

WBuck
WBuck

Reputation: 5501

The anObj variable should be of type std::unique_ptr<Foo> and not a Foo*.

Code should be:

std::unique_ptr<Foo>& anObj{ myVec[ 0 ] };

Or

Foo* anObj{ myVec[ 0 ].get( ) };

Upvotes: 3

Related Questions