将 std::forward 与转发参考一起使用
Using std::forward with a forwarding reference
是这个功能吗
template< typename T >
void foo( T&& in )
{
bar( std::forward<T>( in ) );
}
相当于
template< typename T >
void foo( T&& in )
{
bar( std::forward<T&&>( in ) );
}
转发参考 T&&
传递给 std::forward
?
是的,这些是等价的,但惯用的方法是使用普通的 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
的 return 类型为例:
| 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。
是这个功能吗
template< typename T >
void foo( T&& in )
{
bar( std::forward<T>( in ) );
}
相当于
template< typename T >
void foo( T&& in )
{
bar( std::forward<T&&>( in ) );
}
转发参考 T&&
传递给 std::forward
?
是的,这些是等价的,但惯用的方法是使用普通的 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
的 return 类型为例:
| 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。