Этот код (доступен по адресу http://ideone.com/Mo7fQr)
template<typename T>
void f(const T&) { std::cout << "const T& overload\n"; }
template<typename T>
void f(T&&) { std::cout << "T&& overload\n"; }
int main()
{
const int x = 0;
f(x); // calls const T& overload
f(std::move(x)); // calls T&& overload
}
первый вызов f
(с lvalue) вызывает перегрузку const T&
, а второй вызов (с rvalue) вызывает перегрузку T&&
. По крайней мере, это происходит с gcc 4.8.1 и самой последней версией VC++ (VC12).
Думаю, я понимаю, почему второй вызов разрешается именно так: потому что первый шаблон создает экземпляр с параметром const int&
, в то время как второй шаблон создает экземпляр с параметром const int&&
, и поскольку аргумент, передаваемый на сайте вызова, является значением r, он предпочтительнее привязывается к ссылке rvalue. (Я полагаю, что это указано в стандарте С++ 11 в 13.3.3.2/3, пункт 1, пункт 4.)
Но при первом вызове f
оба шаблона создают экземпляры, принимающие параметр типа const int&
. Так почему же первый шаблон предпочтительнее, когда передается const
lvalue?