Может быть продублировано этот.
Я читаю Эффективный Современный C ++. Под Item 1
Я нашел случай для универсальной ссылки:
Для последнего примера f(27);
Я сделал тест под VS2013.
void process(int& x)
{
std::cout << "int&" << std::endl;
}
void process(int&& x)
{
std::cout << "int&&" << std::endl;
}
template<typename T>
void f(T&& param)
{
std::cout << "------------------------------------------------" << std::endl;
if (std::is_lvalue_reference<T>::value)
{
std::cout << "T is lvalue reference" << std::endl;
}
else if (std::is_rvalue_reference<T>::value)
{
std::cout << "T is rvalue reference" << std::endl;
}
else
{
std::cout << "T is NOT lvalue reference" << std::endl;
}
std::cout << "param is: " << typeid(param).name() << std::endl;
process(std::forward<T>(param));
process(param);
}
int getINT()
{
int x = 10;
return x;
}
int _tmain(int argc, _TCHAR* argv[])
{
f(10);
f(getINT());
return 0;
}
Вот вывод:
------------------------------------------------
T is NOT lvalue reference
param is: int
int&&
int&
------------------------------------------------
T is NOT lvalue reference
param is: int
int&&
int&
Я обнаружил, что внутри функции шаблона, без std::forward<T>(param)
, process(int& x)
будет называться, но в соответствии с книгой, тип для param
должна быть rvalue ссылка, так process(int&& x)
должен быть назван. Но это не так. Это я что-то неправильно понимаю?
Вот ссылка на пересылку, которую я нашел от других нить:
Вы путаете типы с категории значений. В качестве именованного параметра param
это значение, то для process(param);
process(int& x)
будет называться.
Вот почему мы должны использовать std::forward
с экспедиционная ссылка; std::forward<T>(param)
новообращенные param
для этого случая, то process(int&& x)
будет называться (как и ожидалось).
Других решений пока нет …