Понимание вывода аргумента шаблона с помощью rvalue/lvalue
это продолжение от шаблон функции не распознает lvalue
позволяет играть со следующим кодом:
#include <iostream>
template <class T>
void func(T&&) {
std::cout<<"in rvaluen";
}
template <class T>
void func(const T&) {
std::cout<<"in lvaluen";
}
int main()
{
double n=3;
func<double>(n);
func(n);
}
он печатает:
in lvalue
in rvalue
Я не понимаю, что происходит во втором звонок. Как компилятор разрешить параметр шаблона ? Почему нет никакой двусмысленности ?
1 ответов
когда вы говорите func<double>(n), нет аргумента дедукции, так как вы указываете аргумент, и поэтому выбор между func(double &&) и func(const double &). Первый не жизнеспособен, потому что ссылка rvalue не может привязываться к lvalue (а именно n).
только func(n) выполняет вывод аргумента. Это сложная тема, но в двух словах, у вас есть два возможных кандидата:
T = double &: func(T &&) --> func(double &) (first overload)
T = double: func(const T &) --> func(const double &) (second overload)
первая перегрузка строго лучшая, потому что она требует одного меньше преобразование значения аргумента (а именно с double to const double).
волшебный ингредиент-это "справочники рушится", что означает T && может быть ссылка lvalue, когда T сам по себе является ссылочным типом (specificaly,double & && становится double &, и это позволяет существовать первому выводу).