ProgrammerGuy123
ProgrammerGuy123

Reputation: 357

Convert Object to std::unique_ptr

I've got a simple noob question that I can't find an answer to:

In C++ how do you convert a regular object

int i;

into a std::unique_ptr?

std::unique_ptr<int> iptr = &i; //invalid
std::unique_ptr<int> iptr = static_cast<std::unique_ptr<int>>(&i); //invalid

Thanks.

Upvotes: 7

Views: 8970

Answers (4)

Jesse Good
Jesse Good

Reputation: 52365

I believe this will work:

int i;
auto deleter = [](int *ptr){};
std::unique_ptr<int, decltype(deleter)> iptr(&i, deleter);

You have to provide a custom deleter that does nothing. The default deleter cannot delete an automatic variable not allocated by new. (However, this defeats the purpose of using a smart pointer, but shows that it is possible).

Upvotes: 1

xol
xol

Reputation: 119

When the unique_ptr will be destroyed what would happen ? Or the other way, when the variable gets out of scope ? It makes no sense actually

Upvotes: 0

Joseph Mansfield
Joseph Mansfield

Reputation: 110658

You don't. i was not dynamically allocated so it doesn't need to be deleted. If you wrapped a smart pointer around its address, it would do delete &i at some point and give you undefined behaviour. You should only wrap something you have newed in a smart pointer, like so:

std::unique_ptr<int> ptr(new int(5));

The whole point of a smart pointer is that it manages the lifetime of a dynamically allocated object for you. i has automatic storage duration so will be destroyed at the end of its scope. You don't need anything to help you with that.

Upvotes: 5

Puppy
Puppy

Reputation: 146930

You don't. That object cannot be deleted by delete, which is what the unique_ptr is going to do. You need

auto iptr = make_unique<int>();

Here, we define make_unique as a utility function identical to make_shared, which should have been Standard but unfortunately was overlooked. Here's the implementation in brief:

template<typename T, typename... Args> std::unique_ptr<T> make_unique(Args&&... args) {
    return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}

Upvotes: 12

Related Questions