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;
