使用带转发引用的std :: forward

时间:2016-11-29 16:25:54

标签: c++ templates forwarding

这个功能

retail_id

相当于

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&&

1 个答案:

答案 0 :(得分:1)

是的,这些是等价的,但惯用的方法是使用普通的T

以下是在C ++ 14中定义forward函数模板的方法:

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