2016-11-29 15 views
3

Является ли данная функцияИспользование станд :: вперед со ссылкой переадресации

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?

+3

Эмпирическое испытание: http://melpon.org/wandbox/permlink/mJ0gobWkiplIRMMJ –

ответ

1

Да, это эквивалент, но идиоматический способ - использовать простой 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.