Почему константные значения связываются иначе, чем константные значения, заданные T & amp; & amp; и const T & amp; Перегрузки?

Для этого кода (доступно на 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 в п. 1 пункта 13.3.3.2/3).

Но для первого звонка fоба шаблона создают экземпляр типа const int&, Так почему первый шаблон предпочтительнее, когда const Значение передается в?

1

Решение

Когда одна и та же специализация шаблона функции может быть сгенерирована из более чем одного объявления, объявления устраняются с помощью частичное упорядочение шаблонов функций как описано в стандарте C ++ 11 §14.5.6.2 Частичное упорядочение шаблонов функций [temp.func.order]. Компилятор определяет, какой из шаблонов является наиболее специализированным, и предпочитает его.

В вашем примере const T& перегрузка f является более специализированным, чем T&& перегрузки. Наглядно, T&& может быть выведено на все, что const T& может, но не наоборот, так const T& является более конкретным, и поэтому его перегрузка функции является более специализированной.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]