hellow
hellow

Reputation: 13420

Move object into unique_ptr

I have code similar to this:

#include <iostream>
#include <memory>
#include <optional>

class D { 
    D(int i) : i(i), private_member('p') {}
    char private_member;
  public:
    D(const D&) = delete;
    D &operator=(const D&) = delete;
    
    D(D &&) = default;
    D &operator=(D &&) = default;
    
    static std::optional<D> try_create(int i) {
        return i > 10 ? std::make_optional<D>(i) : std::nullopt;
    }
    int i;
};

void accept_unique_ptr_only(std::unique_ptr<D> &ptr) {}

int main() {
    const auto d1 = D::try_create(10);
    const auto d2 = D::try_create(11);
    
    std::cout << (d1.has_value() ? std::to_string(d1->i) : "none1") << std::endl;
    std::cout << (d2.has_value() ? std::to_string(d2->i) : "none2") << std::endl;
}

The class D comes from an external library, so there's no chance to change it, sadly.

While this works, I need to obtain a std::unique_ptr. D does implement the move constructor, so I thought I can just move the D into a std::unique_ptr, but I can't find a method or construtor that allows me to do it.

What is the best way to move an instance of D into a std::unique_ptr, without access to the constructor itself?

Upvotes: 1

Views: 2371

Answers (1)

kmdreko
kmdreko

Reputation: 59942

Use std::make_unique, so something like this:

// non-const
auto d1 = D::try_create(10);

// accounting for empty option
auto d1ptr = d1 ? std::make_unique(std::move(*d1)) : std::unique_ptr<D>();

The resulting unique_ptr will either own a D or it won't depending on the std::optional. You have to make d1 non-const because you need non-const access to the inner D in order to move from it.

Upvotes: 4

Related Questions