Понимание вывода аргумента шаблона с помощью 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 &
, и это позволяет существовать первому выводу).