是的,这些都是等价的,但惯用的方式是使用普通的T
。
这里是forward
函数模板在C++ 14定义了如何:
1)
template< class T >
constexpr T&& forward(typename std::remove_reference<T>::type& t) noexcept;
2)
template< class T >
constexpr T&& forward(typename std::remove_reference<T>::type&& t) noexcept;
首先,让我们来修改你的例子有点使类型减少混乱:
template< typename U >
void foo(U&& in)
{
using T = U; // or U&&
bar(std::forward<T>(in));
}
现在,我们考虑返回类型forward
- T&&
,int
用作示例:
| U | T | T&& |
| int | int | int&& |
| int& | int& | int& && = int& |
| int&& | int&& | int&& && = int&& |
与using T = U&&
| U | U&& (also T) | T&& |
| int | int&& | int&& && = int&& |
| int& | int& && = int& | int& && = int& |
| int&& | int&& && = int&& | int&& && = int&& |
所以,结果类型是相同的。
至于参数,typename std::remove_reference<T>::type
是一个死牌。我使用remove_ref<T>
的可读性:
| T | remove_ref<T> | remove_ref<T>& | remove_ref<T>&& |
| int | int | int& | int&& |
| int& | int | int& | int&& |
| int&& | int | int& | int&& |
正如你可以看到,这是不依赖于模板参数的参考岬可言。
参考折叠更深入的解释here。
实证检验:http://melpon.org/wandbox/permlink/mJ0gobWkiplIRGMJ –