将 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