With forwarding functions using a template parameter, the idiom is to forward using the typename T
, e.g.
template <typename T>
void fwd(T &&x) {
some_func(std::forward<T>(x));
}
Equivalent approach when using a forwarding function (or lambda) that takes an auto type parameter:
void fwd(auto &&x) {
some_func(std::forward<decltype(x)>(x));
}
In the above decltype(x)
is not necessarily the same as the type of T
in the previous example. E.g. fwd(3)
deduces T
to int
while decltype(x)
is int&&
.
Can someone explain why we use T
in one case vs. decltype(x)
as the template parameter to std::forward
above? Is the end result always guaranteed to be identical based on the implementation of std::forward
?
CodePudding user response:
void fwd(auto &&x)
is a c 20 shorthand for template <typename T> void fwd(T &&x)
. But in this case you don't have type to refer to. You can write this:
void fwd(auto &&x) {
using T = std::remove_reference_t<decltype(x)>;
some_func(std::forward<T>(x));
}
Here T equals to T in original version, but it doesn't matter much.
std::forward<T>
and std::forward<std::remove_reference_t<T>>
are equal, because its signature defined like this:
template< class T >
constexpr T&& forward( std::remove_reference_t<T>&& t ) noexcept;