Does std::make_unique have any efficiency benefits like std::make_shared?
Compared to manually constructing std::unique_ptr:
std::make_unique<int>(1); // vs std::unique_ptr<int>(new int(1)); 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:
make_unique does not require redundant type usage. unique_ptr<T>(new T()) -> make_unique<T>()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.
std::unique_ptr and std::shared_ptr are why we can tell people to "never use new."make_shared and so make_unique is the final piece that was previously missing.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.std::make_unique and std::make_shared are there for two reasons:
std::unique_ptr or std::shared_ptr constructors. (See the Notes section here.)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.
std::make_shared will ensure that at least one of them gets wrapped in the smart pointer before the other memory allocation occurs, hence no leaks.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.
Consider function call
void function(std::unique_ptr<A>(new A()), std::unique_ptr<B>(new B())) { ... } Suppose that new A() succeeds, but new B() throws an exception: you catch it to resume the normal execution of your program. Unfortunately, the C++ standard does not require that object A gets destroyed and its memory deallocated: memory silently leaks and there's no way to clean it up. By wrapping A and B into std::make_unique() calls, you are sure the leak will not occur:
void function(std::make_unique<A>(), std::make_unique<B>()) { ... } The point here is that std::make_unique<A>() and std::make_unique<B>() return temporary objects, and cleanup of temporary objects is correctly specified in the C++ standard: their destructors will be triggered and the memory freed. So, if you can, always prefer to allocate objects using std::make_unique() and std::make_shared().
make_sharedhave any efficiency over just writing the long hand code?make_sharedcan allocate both the space for the object and the space for the control block together in a single allocation. The cost of that is that the object cannot be deallocated separately from the control block, so if you useweak_ptra lot then you may end up using more memory.