Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 683
ProgrammerGuy123 Avatar asked Dec 25 '12 21:12

ProgrammerGuy123


People also ask

Can I convert shared_ptr to unique_ptr?

Afterword. The flawless conversion of an std::unique_ptr to a compatible std::shared_ptr makes it possible to write efficient and safe factory functions. However, note that an std::shared_ptr cannot be converted to an std::unique_ptr.

What is std :: unique_ptr?

std::unique_ptr is a smart pointer that owns and manages another object through a pointer and disposes of that object when the unique_ptr goes out of scope. The object is disposed of, using the associated deleter when either of the following happens: the managing unique_ptr object is destroyed.

Can you copy unique_ptr?

A unique_ptr does not share its pointer. It cannot be copied to another unique_ptr , passed by value to a function, or used in any C++ Standard Library algorithm that requires copies to be made. A unique_ptr can only be moved.

Why would you choose shared_ptr instead of unique_ptr?

In short: Use unique_ptr when you want a single pointer to an object that will be reclaimed when that single pointer is destroyed. Use shared_ptr when you want multiple pointers to the same resource.


3 Answers

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)...));
}
like image 143
Puppy Avatar answered Sep 26 '22 13:09

Puppy


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.

like image 20
Joseph Mansfield Avatar answered Sep 24 '22 13:09

Joseph Mansfield


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).

like image 37
Jesse Good Avatar answered Sep 25 '22 13:09

Jesse Good