As far as I understand, c++14 introduced
std::make_unique because, as a result of the parameter evaluation order not being specified, this was unsafe:
f(std::unique_ptr<MyClass>(new MyClass(param)), g()); // Syntax A
(explanation: if the evaluation first allocates the memory for the raw pointer, then calls
g() and an exception is thrown before the
std::unique_ptr construction, then the memory is leaked)
std::make_unique was a way to constrain the call order, thus making things safe:
f(std::make_unique<MyClass>(param), g()); // Syntax B
Since then, c++17 has clarified the evaluation order, making Syntax A safe too, so here's my question: is there still a reason to use
std::unique_ptr's constructor in c++17? Can you give some examples?
As of now, the only reason I can imagine is that it allows to type
MyClass only once (assuming you don't need to rely on polymorphism with
std::unique_ptr<Base>(new Derived(param))). However, that seems like a pretty weak reason, especially when
std::make_unique doesn't allow to specify a deleter while
std::unique_ptr's constructor does.
Edit: Just to be clear, I'm not advocating in favor of removing
std::make_unique from the STL (keeping it makes sense at least for backward compatibility), but rather wondering if there are still situations in which it is strongly preferred to
You're right that the main reason was removed. There are still the don't use new guidelines and that it is less typing reasons (don't have to repeat the type or use the word
new). Admittedly those aren't strong arguments but I really like not seeing
new in my code.
Also don't forget about consistency. You absolutely should be using
make_shared so using
make_unique is natural and fits the pattern. It's then trivial to change
std::make_shared<MyClass>(param) (or the reverse) where the syntax A requires much more of a rewrite.