Not registered yet?
Register now! It is easy and done in 1 minute and gives you access to special discounts and much more!
Does std::make_unique have any efficiency benefits like std::makes_shared?
Compared to manually constructing std::unique_ptr:
std::make_unique<int>(1); // vs
A reason why you would have to use std::unique_ptr(new A()) or std::shared_ptr(new A()) directly instead of std::make_*() is being unable to access the constructor of class A outside of current scope.
The motivation behind make_unique is primarily two-fold:
make_unique is safe for creating temporaries, whereas with explicit use of new you have to remember the rule about not using unnamed temporaries.
foo(make_unique<T>(), make_unique<U>()); // exception safe
foo(unique_ptr<T>(new T()), unique_ptr<U>(new U())); // unsafe*
The addition of make_unique finally means we can tell people to 'never' use new rather than the previous rule to "'never' use new except when you make a unique_ptr".
There's also a third reason:
None of the reasons involve improving runtime efficiency the way using make_shared does (due to avoiding a second allocation, at the cost of potentially higher peak memory usage).
* It is expected that C++17 will include a rule change that means that this is no longer unsafe. See C++ committee papers P0400R0 and P0145R3.
It would make more sense to say std::unique_ptr and std::shared_ptr are why we can tell people to "never use new."
@TimothyShields Yeah, that's what I mean. It's just that in C++11 we have make_shared and so make_unique is the final piece that was previously missing.
Any way you could mention briefly, or link to, the reason for not using unnamed temporaries?
Actually, from stackoverflow.com/a/19472607/368896, I've got it... From that answer, consider the following function call f: f(unique_ptr<T>(new T), function_that_can_throw()); - to quote the answer: The compiler is allowed to call (in order): new T, function_that_can_throw(), unique_ptr<T>(...). Obviously if function_that_can_throw actually throws then you leak. make_unique prevents this case. So, my question is answered.
f(unique_ptr<T>(new T), function_that_can_throw());
@bames53 Unfortunately there is still need to use raw new if you want to pass a custom facet to std::locale (overload 7).
@bames53 Have there been any news regarding the footnote?
@tambre The linked papers are part of the C++17 draft, and there shouldn't be any significant changes between now and publication later this year. Clang already implements these rules. It's not clear from gcc's status page if they do or not yet.
Took a really long time to see why it is now safe, but yeah it is. BTW thanks for updating your answer
std::make_unique and std::make_shared are there for two reasons:
It's not really about runtime efficiency. There is the bit about the control block and the T being allocated all at once, but I think that's more a bonus and less a motivation for these functions to exist.
They're also there for exception-safety.
@0x499602D2 And that, good addition. This page talks about that.