1

Just wondering if there is a way to move an object holding a unique_ptr into a vector of those objects? Example:

class A
{
public:
   std::unique_ptr<someData> ptr;
};

std::vector<A> objects;
A myObject;

//move myObject to objects???

Now, is there a way I could move myObject into objects and avoiding unique_ptr errors?

lorro
  • 10,687
  • 23
  • 36
Thicc Theo
  • 65
  • 5

1 Answers1

1

You'll need to do std::move:

std::vector<A> objects;
A myObject;

objects.push_back(std::move(myObject));
lorro
  • 10,687
  • 23
  • 36
  • can I use emplace_back()? Also, in my actual case, ptr is actually a std::vector> – Thicc Theo Jun 30 '22 at 21:37
  • 1
    @ThiccTheo depending on `A`'s ctor(s), likely you can. It doesn't (shouldn't) matter if it's a `vector` as long as move assignment operator is defined for it (for `std::vector`, it is defined). – lorro Jun 30 '22 at 21:40
  • 2
    @ThiccTheo `emplace_back` is for directly constructing new objects in the vector, not for moving in existing ones. Also, please ask the question you intend to ask, and not some facsimile of it. – Paul Sanders Jun 30 '22 at 21:45
  • @PaulSanders — `emplace_back` constructs an element from its argument(s). There’s no reason it’s argument can’t be an object of the type that the vector holds. – Pete Becker Jun 30 '22 at 21:57
  • @PeteBecker I know, but there's little point in using it this way (with any reasonable `A`). – Paul Sanders Jun 30 '22 at 21:57
  • `objects.push_back(std::move(myObject));` and `objects.emplace_back(std::move(myObject));` gives identical (bad) code. The damage is already done by calling the constructor for `A`. With `emplace_back` you idealy want to construct a new object in-place instead of invoking the copy/move constructor on an existing object. – Goswin von Brederlow Jun 30 '22 at 22:27
  • @GoswinvonBrederlow 'bad' is a bit judgemental... if `myObject` comes from an argument, then you'll need to call `push_back()` / `emplace_back()`, cmiiw. If you have the pointer, of course you can do better via `emplace_back()`, but that was not the original question that this started from. – lorro Jun 30 '22 at 22:37
  • @lorro My point was that `emplace` with an already constructed object has no benefit over `push_back`. Both will invoke the copy/move constructor. `emplace` only becomes a benefit if you don't already have an object. Pete was trying to save something by constructing an element but that is not possible. Imho `emplace_back(object)` is code smell. It suggests something is saved compared to `push_back` where it isn't. – Goswin von Brederlow Jun 30 '22 at 22:47
  • As for *“can I use `emplace_back()`”*: Think of `emplace_back()` as calling a constructor of the `vector` element type. If you use `std::move(existing_A)`, then `emplace_back()` and `push_back()` are exactly the same thing, because `push_back()` has an overload for `A&&`. However, if `A` has a complex constructor with multiple arguments that can benefit from perfect-forwarding (say, two vectors, any of which can be an R-value or an L-value), then `emplace_back()` will be better than `push_back()` … unless `A` has a perfect-forwardming (templated) constructor with the exact same effect. – Andrej Podzimek Jun 30 '22 at 23:05
  • @GoswinvonBrederlow — I wasn’t “trying to save” anything. I have no idea how you got that from my comment. – Pete Becker Jul 01 '22 at 01:50