За този код (достъпен на 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&&
и тъй като аргументът, подаден на сайта за извикване, е rvalue, той преференциално се свързва с препратката към rvalue. (Вярвам, че това е посочено в стандарта C++11 в 13.3.3.2/3 bullet 1 sub-bullet 4.)
Но за първото извикване на f
и двата шаблона инстанцират приемането на параметър от тип const int&
. Така че защо първият шаблон е предпочитан, когато се подава const
lvalue?