Ответ 1
Это просто соответствует тому, что мы ожидаем в целом от вычитания типа шаблона:
template <class T> void vfoo(T );
template <class T> void lfoo(T& );
template <class T> void cfoo(T const& );
template <class T> void ffoo(T&& );
std::string x;
vfoo(x); // deduce T = std::string
lfoo(x); // deduce T = std::string
cfoo(x); // deduce T = std::string
ffoo(x); // deduce T = std::string& !
ffoo(std::move(x)); // deduce T = std::string
Из оригинальной статьи, мой удар:
При выводе типа шаблона функции с использованием аргумента lvalue, совпадающего с ссылкой на rvalue, тип выводится как ссылочный тип lvalue. Когда вычитанию присваивается аргумент rvalue, вывод типа происходит так же, как и для других типов.
Это случай вывода lvalue, который является исключительным, поэтому он получает дополнительное предложение в правилах вывода типа. Случай rvalue типичен - он выстраивается в линию с простой ментальной моделью вставки в выведенных типах, чтобы увидеть, какую функцию вы оказываете. Вызывается T&&
с помощью std::string
? Получите T = std::string
, чтобы аргумент читал std::string&&
. Проверьте.