Assume namespace std
throughout.
The C++14 committee draft N3690 defines std::make_unique
thus:
[n3
Quoting from the original proposal:
T[N]
As of N3485,
unique_ptr
doesn't provide a partial specialization forT[N]
. However, users will be strongly tempted to writemake_unique<T[N]>()
. This is a no-win scenario. Returningunique_ptr<T[N]>
would select the primary template for single objects, which is bizarre. Returningunique_ptr<T[]>
would be an exception to the otherwise ironclad rule thatmake_unique<something>()
returnsunique_ptr<something>
. Therefore, this proposal makesT[N]
ill-formed here, allowing implementations to emit helpfulstatic_assert
messages.
The author of the proposal, Stephan T. Lavavej, illustrates this situation in this video on Core C++ (courtesy of chris), starting from minute 1:01:10 (more or less).
To me the third overload looks superfluous as does not change the fact that the other overloads won't match T[N]
and it does not seem to help to generate better error messages. Consider the following implementation:
template< typename T, typename... Args >
typename enable_if< !is_array< T >::value, unique_ptr< T > >::type
make_unique( Args&&... args )
{
return unique_ptr< T >( new T( forward< Args >( args )... ) );
}
template< typename T >
typename enable_if< is_array< T >::value && extent< T >::value == 0, unique_ptr< T > >::type
make_unique( const size_t n )
{
using U = typename remove_extent< T >::type;
return unique_ptr< T >( new U[ n ]() );
}
When you try to call std::make_unique<int[1]>(1)
, the error message lists both candidates as disabled by enable_if
. If you add the third, deleted overload, the error message lists three candidates instead. Also, since it is specified as =delete;
, you can not provide a more meaningful error message in the third overload's body, e.g., static_assert(sizeof(T)==0,"array of known bound not allowed for std::make_shared");
.
Here's the live example in case you want to play with it.
The fact that the third overload ended up in N3656 and N3797 is probably due to the history of how make_unique
was developed over time, but I guess only STL can answer that :)