The function std::make_shared<T>() is most often preferred to std::shared_ptr<T> {new T}, because it will only make one allocation, as opposed to two allocations in the second example. There are a few other differences, as detailed in cppreference on std::make_shared.
To my knowledge, the case is different for std::make_unique<T>() vs. std::unique_ptr<T> {new T}. Before C++17, we needed the make_ functions to deduce template arguments, but since C++17, the compiler can derive them from the initialization statement.
Hence my question: what are the advantages and disadvantages of either approach of constructing a unique_ptr? Is there a specific case for which make_unique offers an advantage (other than template parameter deduction in earlier C++ editions)?
The advantages are:
std::make_unique<T>(/* initialiser args */):
T once.make_shared as well.new keyword.std::unique_ptr<T>{ ::new T/* initialiser */ }:
make_unique_for_overwrite.T with auto in C++23:std::unique_ptr<T>{ ::new auto(function_returning_a_T()) }.
T's constructor args are by-value, this can also skip some moves:
struct X { X(std::mutex); }; // std::mutex used as example for immovable type
// auto x = std::make_unique<X>(std::mutex()); // Doesn't work
auto x = std::unique_ptr<X>{ ::new X(std::mutex()) }; // Works
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With