I'd argue that in a language with the `new` keyword, nothing is more easy or natural than invoking it. `auto Foo = std::make_unique<Foo>(args);` is absolutely the right thing to do, but would you really be surprised to find `auto foo = new Foo(args);`?
I absolutely agree unique pointers are the right call. They just aren't necessarily the easy or natural call.
The contrast is rust where all ptrs are, by default, unique ptr and the compiler validates that for you.
It is already hard to educate people on modern language features and adoption of static analysers that enforce Core Guidelines.
Who would write the books and teaching materials for #pragma modern_defaults, and ensure it would be accepted into ISO?
Foo foo{args};
Which is simpler than the other cases, more correct and more performant. The rare few times dynamic allocation of something that is not an array with new is needed is when you have polymorphic types - but then, the user code generally calls a factory function instead of new. auto foo = std::make_unique<Foo>(args);
Think about explaining this to a new C++ developer.This will feel much more natural to most developers:
var foo = new Foo(args); Foo foo(args);
Sometimes an object has to be on the heap as its own separate allocation (rather than on the stack or as a data member), but I notice that some new developers who come to C++ from some other language use the heap way too much.How's this:
The code allocates and initializes a new Foo instance with args. By using make_unique you guarantee that the destructor is called when foo goes out of scope for any reason.
This is true, but we shouldn't be encouraging people to reach for new/delete these days; auto Foo = std::make_unique<Foo>(args); does the right thing in a surprisngly large number of cases. It's not the only tool available, but it's a really damn good one.