Underprivileged unique pointers: retrofitting make_unique

std::shared_ptr<Value> is one of the starlets in C++11’s recently polished standard template library. shared_ptrs work just like normal C-style pointers except that they keep track of how many pointers point to the same object. Once the last shared_ptr pointing to an object goes out of scope, the object pointed at will be deleted. For convenience, the standard library offers the factory function std::make_shared<Value>():

auto value = std::make_shared<Value>("a", "few", "arguments");

std::make_shared<Value>() creates a new object of type Value, where the arguments given to make_shared() are forwarded to the constructor of Value. The newly created object is immediately wrapped in a std::shared_ptr<Value>, which is then returned to the caller.

How the standard treats unique_ptr

With std::unique_ptr<Value>, there is another, equally important smart pointer in the new standard library (sorry std::weak_ptr<Value>, I did not mean to hurt your feelings): The difference between unique_ptr and shared_ptr is that you can copy shared_ptrs while you cannot copy std::unique_ptrs. This restriction leads to unique_ptrs being slightly more efficient than shared_ptrs.

There is another difference when it comes to usability. The standard inexplicably lacks a facility similar to std::make_shared<Value>(). Instead, you need to create a unique_ptr like this:

std::unique_ptr<Value> value(new Value("a", "few", "arguments"));

This is rather ugly, in particular when held right next to the shared_ptr example above. There is some duplication (Value is specified twice) and there is a naughty call to new, which suggests manual resource management even though it is not.

Your very own make_unique

With a few lines of code, we can elevate the underprivileged unique_ptr to what it should be; an equally treated sibling of shared_ptr:

#include <memory>

template <typename Value, typename ... Arguments>
std::unique_ptr<Value> make_unique(Arguments && ... arguments_for_constructor)
{
	return std::unique_ptr<Value>(
		new Value(std::forward<Arguments>(arguments_for_constructor)...)
	);
}

You should put this little function in a header file, perhaps one ingeniously named make_unique.h. It will allow you to create unique_ptrs like this:

auto value = make_unique<Value>("a", "few", "arguments");

There, the duplication of Value is gone and there is no suspicious new to be seen (at least with one and a half eyes closed).

2 Replies to “Underprivileged unique pointers: retrofitting make_unique”

  1. Considering how wise the guys who make C++11 are, and that this part of the standard was not rushed, I really have to ask: is there any reason why this useful function is missing from the standard ? I mean, there are all kinds of make_* functions in there.

    The thing to do would be to submit a defect report, see how the WG reacts.

    1. Good question. I feel it is strange that std::make_unique does not exist. In his very own blog, Herb Sutter (chair of the ISO C++ standards committee) writes:

      That C++11 doesn’t include make_unique is partly an oversight, and it will almost certainly be added in the future.

      If someone had a time machine (SVN does not count), I guess this would be an opportunity to put it to good use…

Leave a Reply

Your email address will not be published. Required fields are marked *