В чем смысл шаблона?

Используя шаблоны:

template <class T>
T GetMax (T a, T b) {
return (a>b?a:b);
}

а потом

int main () {
int i=5, j=6, k;
long l=10, m=5, n;
k=GetMax(i,j);           // line 1
n=GetMax<int>(l,m);      // line 2
n=GetMax<double>(l,m);   // line 3
cout << k << endl;
cout << n << endl;
return 0;
}

мои вопросы:

почему я должен сделать это:

n=GetMax<int>(l,m);      // line2

если я могу сделать

n=GetMax(l,m);      // line 2

а почему это компилируется?

n=GetMax<double>(l,m);

когда L а также м целые числа, которые сильно отличаются от двойных?

1

Решение

В этом контексте вы можете думать, что создание шаблона является простой заменой текста (это не так уж и далеко), то есть, когда вы выяснили параметры шаблона. Так:

  1. Вы позволяете компилятору выяснить тип из операндов. Так как они совпадают, T считается int, Вы можете найти точную логику ранжирования соответствующих параметров шаблона в стандарте. Ваш случай довольно прост.

После определения параметра шаблона выполняется подстановка, поэтому ваша функция выглядит следующим образом:

int GetMax (int a, int b) {
return (a>b?a:b);
}

Он компилируется, когда вы используете несколько параметров и имеете много возможных совпадений с наследованием и т. Д. И т. Д.

В вашем случае вы можете вызвать равные совпадения, используя два разных типа для параметров, т.е. GetMax(i,l), T имеет двух кандидатов: double как intи оба одинаково хороши.

Это связано со знаменитым SFINAE (ошибка замены не является ошибкой). Компилятор пытается сгенерировать версии для возможных комбинаций параметров, и в случае неудачи он не учитывается для окончательного ранжирования. В вашем случае две замены прошли успешно.

  1. Вы прямо заявляете, что T int, Таким образом, компилятор не вызывает автоматического сопоставления параметров. Созданная версия выглядит так же, как 1.

  2. Вы прямо заявляете, что T в double, Опять же, компилятор не вызывает никакой логики относительно типов.

Слепо генерирует версию для doubleи использует это:

 double GetMax (double a, double b) {
return (a>b?a:b);
}

Это законно, чтобы передать int к функции, использующей doubleпроисходит неявное преобразование.

Это совершенно законно:

void f(double d) {};

int main(){
int i = 5;
f(i);
}

Нижняя линия:

Выяснение типов шаблонов — это не просто логика, а вызов функции. Думайте об этом как об отдельных фазах. Вывод типа разработан, чтобы иметь смысл для вызова, но это отдельная вещь.

3

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

Вы можете опустить типы в шаблонных функциях, потому что они вычитаются во время компиляции

И второй вопрос, нет ошибки, потому что целые числа изящно отступают в два раза, поэтому они будут преобразованы и использованы как двойные в логике вашего шаблона.

0

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