3.2.1 make_unique

What was the problem

PIC <memory>

C++11 introduced smart pointers in the standard library, with std::unique_ptr and std::shared_ptr. For the latter the idiomatic creation code would use std::make_shared, which would have the benefit to create storage for the control block and the actual object into a single allocation. On the other hand, std::unique_ptr has no control block, so it made sense at the time not to have specialized creation functions for it.

There is another use case though, where such function can help:

create_form 
  (std::unique_ptr<widget>(new label("Everything is fine.")), 
   std::unique_ptr<widget>(new icon("resources/alert.png")));

See, since there is no guarantee on the order of evaluation of function arguments, the compiler is free to sequence them as follows:

  1. new label(…)
  2. new icon(…)
  3. std::unique_ptr(…)
  4. std::unique_ptr(…)

Now, if the constructor of icon throws an exception, then the label won’t ever be destroyed, nor its memory released during the program execution.

How the Problem is Solved

This can be solved by wrapping the allocation in a function, a function provided by the standard library for example.

create_form 
  (std::make_unique<label>("Everything is fine."), 
   std::make_unique<icon>("resources/alert.png"));

With this code, the order of evaluation does not matter. If the first argument is built before the second, then its memory already managed by the smart pointer, so even if the construction of the second argument throws, the object will be destroyed and the memory will be released. The reasoning is the same if the second argument is built before the first.

As a bonus, this is also less verbose.