C ++ 14 Ссылка на функцию пересылки шаблонов, выведенная явно указателем - PullRequest
0 голосов
/ 12 декабря 2018

Объясните, пожалуйста, что не так с этим кодом?

Необычное поведение заключается в том, что f3 работает, когда неявно выводится, но не работает, когда принудительно специализируется.

template<typename T>
void f1(T x) {}

template<typename T>
void f2(T& x) {}

template<typename T>
void f3(T&& x) {}

int main()
{
  int x = 0;

  f1(x); // ok
  f2(x); // ok
  f3(x); // ok

  f1<int>(x); // ok
  f2<int>(x); // ok
  f3<int>(x); // error
}

VS2017.Сообщение компилятора:

ошибка C2664: «void f3 (T &&)»: невозможно преобразовать аргумент 1 из «int» в «T &&»

Я думал, что делаю то же самое, явно указав int .И единственное отличие в том, что вычет в этом случае f3(x); был сделан компилятором, а в этом f3<int>(x); мной.

Ответы [ 2 ]

0 голосов
/ 12 декабря 2018

Я не уверен на 100%, пожалуйста, кто-нибудь исправит меня, если я ошибаюсь:

Потому что в случае f3(x) выводимый тип - f3<int&>( int& && ).

0 голосов
/ 12 декабря 2018

Имеется ошибка, так как ссылки на l-значения и l-значения не могут быть использованы для инициализации ссылок на r-значения.Ссылки на R-значения могут быть инициализированы только с помощью r-значений.

Вы можете использовать PRETTY_FUNCTION , чтобы получить вызываемую функцию вместе с выводимыми аргументами.

f1(a); // ok  deduces to void f1(T) [T = A *]
f2(a); // ok  deduces to void f2(T &) [T = A *]
f3(a); // ok  deduces to void f3(T &&) [T = A *&]


f1<A*>(a); // ok . No Deduction as T already specified void f1(T) [T = A *]
f2<A*>(a); // ok .  No Deduction as T already specified to void f2(T) [T = A *]


f3<A*>(a); // Errror becuase l-values and l-values references 
           // cannot be used  to r-value references.
          // R-values references can only be initialized with r-values only. 
...