I'm trying to understand why std::make_shared is declared/implemented the way it is:
template<class _Tp, class ..._Args>
inline _LIBCPP_INLINE_VISIBILITY
typename enable_if
<
!is_array<_Tp>::value,
shared_ptr<_Tp>
>::type
make_shared(_Args&& ...__args)
{
return shared_ptr<_Tp>::make_shared(_VSTD::forward<_Args>(__args)...);
}
What I'm curious about is:
make_shared
accept only rvalue-references? Why there's no overload for reference-to-constant (i.e., const _Args &
)?_VSTD::forward
call?Good explanation or good hyperlink will both be highly appreciated.
Why does make_shared accept only rvalue-references? Why there's no overload for reference-to-constant (i.e., const _Args &)?
This is a universal reference that binds both to r-values and l-values. For r-values the deduced type is T
, for l-values it is T&
.
What's the point of _VSTD::forward call?
When a temporary is bound to an r-value reference, that reference (the name) is not r-value any more. You need to be able to restore the original value category of the value and this is what std::forward<>
is for: to forward the r-value arguments as r-values and l-value arguments as l-values.
Essentially std::forward
applies &&
to T
or T&
. When &&
is applied to
T
it becomes T&&
- the r-value reference, andT&
becomes T&&&
, which is again T&
.