Hmmm... I'm pretty sure this isn't given as a work-around implementation of the future std::make_unique
, but anyway, what the function does is pretty easy to understand, though it requires you to have prior knowledge of new C++11 features.
template <typename TT, typename A>
unique_ptr<TT> make_unique(int i, A && a)
{
return unique_ptr<TT>{new TT{ i, std::forward<A>(a) }};
}
First of all make_unique
is a function template, I really hope you already know that, as the following would require that you have at least the most basic knowledge on what templates does and how templates work.
Now to the non-trivial parts. A && a
there is a function parameter. Specifically, a
is the function parameter whose type is A&&
which is an r-value reference. With its type being a template type parameter, we can deduce its type from whatever the caller passes as an argument to a
. Whenever we have r-value reference and argument type deduction, special deduction rules and reference collapsing kicks-in and we have a so-called "universal reference" which is particularly useful for perfect forwarding functions.
Whenever we have a universal reference (a
in our case), we will almost always want to preserve its original "l-valueness" or "r-valueness" whenever we want to use them. To have this kind of behavior, we should almost always use std::forward
(std::forward<A>(a)
). By using std::forward
, a variable originally passed as an l-value remains an l-value and a variable originally passed as an r-value remains an r-value.
After that, things are just simple
return unique_ptr<TT>{new TT{ i, std::forward<A>(a) }};
Notice the use of the braces. Instead of using parentheses, it is using C++11's uniform initialization syntax of calling constructors. With new TT{ i, std::forward<A>(a) }
, you are dynamically allocating an object of type TT
with the given parameters inside the braces. With unique_ptr<TT>{new TT{ i, std::forward<A>(a) }};
, you are creating a unique_ptr<TT>
whose parameter is the one returned by the dynamic allocation. The unique_ptr<TT>
object now then returned from the function.