Why use std::make_unique in C++17?

依然范特西╮ 提交于 2019-12-02 16:54:50

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_unique<MyClass>(param) to std::make_shared<MyClass>(param) (or the reverse) where the syntax A requires much more of a rewrite.

make_unique distinguishes T from T[] and T[N], unique_ptr(new ...) does not.

You can easily get undefined behaviour by passing a pointer that was new[]ed to a unique_ptr<T>, or by passing a pointer that was newed to a unique_ptr<T[]>.

S.M.

The reason is to have shorter code without duplicates. Compare

f(std::unique_ptr<MyClass>(new MyClass(param)), g());
f(std::make_unique<MyClass>(param), g());

You save MyClass, new and braces. It costs only one character more in make in comparison with ptr.

Yakk - Adam Nevraumont

Every use of new has to be extra carefully audited for lifetime correctness; does it get deleted? Only once?

Every use of make_unique doesn't for those extra characteristics; so long as the owning object has "correct" lifetime, it recursively makes the unique pointer have "correct".

Now, it is true that unique_ptr<Foo>(new Foo()) is identical in all ways1 to make_unique<Foo>(); it just requires a simpler "grep your source code for all uses of new to audit them".


1 actually a lie in the general case. Perfect forwarding isn't perfect, {}, default init, arrays are all exceptions.

Since then, C++17 has clarified the evaluation order, making Syntax A safe too

That's really not good enough. Relying on a recently-introduced technical clause as the guarantee of safety is not a very robust practice:

  • Someone might compile this code in C++14.
  • You would be encouraging the use of raw new's elsewhere, e.g. by copy-pasting your example.
  • As S.M. suggests, since there's code duplication, one type might get changed without the other one being changed.
  • Some kind of automatic IDE refactoring might move that new elsewhere (ok, granted, not much chance of that).

Generally, it's a good idea for your code to be appropriate/robust/clearly valid without resorting to language-laywering, looking up minor or obscure technical clauses in the standard.

(this is essentially the same argument I made here about the order of tuple destruction.)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!