0

Is it possible in C++ to have a constructor that takes a reference to an object, and moves this into a smart pointer? Example:

class A {
public:
    A(std::unique_ptr<std::vector<int>>& v_ptr) : v_ptr(std::move(v_ptr)) {};

    // TODO: wanted constructor with this signature that ideally calls the first constructor
    A(std::vector<int>& v) {}

private:
    std::unique_ptr<std::vector<int>> v_ptr;
}

My intended usage of this class should be something like this:

A a({1, 2, 3});
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Green绿色
  • 1,620
  • 1
  • 16
  • 43
  • 1
    A) Why a unique_ptr to a vector? vector already does memory ownership B) afaik usually if you intend to do a move like this you take things by value (your init list probably wont work with the ref signature since temporaries cant bind to non-const ref and a const ref cant be moved since moving modifies the source) C) `A(std::vector v) : v_ptr(std::make_unique>(std::move(v))) {}` ? – Borgleader Apr 12 '22 at 02:14
  • While legal, `unique_ptr` really should not be passed around using a non-const lvalue reference, as that doesn't convey the proper ownership semantics to the caller. It should be passed around by either value or rvalue reference. – Remy Lebeau Apr 12 '22 at 02:25
  • @RemyLebeau Thanks for this hint. I'll change that. – Green绿色 Apr 12 '22 at 03:20
  • @Borgleader Yes, you're right. I used rvalue references in other locations of my code to achieve this syntax `f({1, 2, 3})`. – Green绿色 Apr 12 '22 at 03:23
  • @Borgleader So, it's better to change the signature of `A` to `A(std::unique_ptr<...> v_ptr)`, so copy the unique pointer? However, I cannot get it compiled then: `../main.cpp:13:55: error: no matching function for call to ‘std::unique_ptr >::unique_ptr(std::remove_reference&>::type)’` – Green绿色 Apr 12 '22 at 03:27
  • @Green绿色 "*so copy the unique pointer?*" - `unique_ptr` can't be copied, only moved. The caller would have to use `std::move()` on a pre-existing `unique_ptr`, thus preserving ownership semantics. "*no matching function for call to ‘unique_ptr(std::vector‌​)’*" - you can't construct a `unique_ptr` from a `vector`. – Remy Lebeau Apr 12 '22 at 03:31
  • @RemyLebeau So, the constructor would be `A(std::unique_ptr> v_ptr) : v_ptr(std::move(v_ptr)) {};` and the call to the constructor `A a(std::move(v_ptr));`? So move twice? – Green绿色 Apr 12 '22 at 03:34
  • @Green绿色 no, because again, you can't construct a `unique_ptr` directly from a `vector`. Borgleader already showed you what you need (#C using `std::make_unique()`). Did you even try it yet? – Remy Lebeau Apr 12 '22 at 03:36
  • @RemyLebeau I see, thanks. However, I'm a little bit confused about this reference and move thing. – Green绿色 Apr 12 '22 at 03:37
  • 2
    @Green绿色 then I suggest you stop what you are doing and go brush up on the fundamentals of how smart pointers work. Get some [decent C++ books](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list), if you need to. They will cover this in detail. – Remy Lebeau Apr 12 '22 at 03:40

0 Answers0