Бьерн Страуструп. Язык программирования С++ Второе дополненное издание


 Разрешение перегрузки для шаблонной функции



Pdf көрінісі
бет161/256
Дата11.07.2022
өлшемі2,87 Mb.
#37591
1   ...   157   158   159   160   161   162   163   164   ...   256
8.5 Разрешение перегрузки для шаблонной функции 
К параметрам шаблонной функции нельзя применять никаких преобразований типа. Вместо этого при 
необходимости создаются новые варианты функции: 
template T sqrt(t); 
void f(int i, double d, complex z) 

complex z1 = sqrt(i); // sqrt(int) 
complex z2 = sqrt(d); // sqrt(double) 
complex z3 = sqrt(z); // sqrt(complex) 
// 
... 

Здесь для всех трех типов параметров будет создаваться по шаблону своя функция sqrt. Если 
пользователь захочет чего-нибудь иного, например вызвать sqrt(double), задавая параметр int, нужно 
использовать явное преобразование типа: 
template T sqrt(T); 
void f(int i, double d, complex z) 

complex z1 = sqrt(double(i)); // sqrt(double) 
complex z2 = sqrt(d); // sqrt(double) 
complex z3 = sqrt(z); // sqrt(complex) 
// 
... 

В этом примере по шаблону будут создаваться определения только для sqrt(double) и sqrt(complex). 
Шаблонная функция может перегружаться как простой, так и шаблонной функцией того же имени
Разрешение перегрузки как шаблонных, так и обычных функций с одинаковыми именами происходит за 
три шага. Эти правила слишком строгие, и, по всей видимости будут ослаблены, чтобы разрешить 
преобразования ссылок и указателей, а, возможно, и другие стандартные преобразования. Как обычно, 
при таких преобразованиях будет действовать контроль однозначности. 
[1] Найти функцию с точным сопоставлением параметров ($$R.13.2); если такая есть, вызвать ее. 
[2] Найти шаблон типа, по которому можно создать вызываемую функцию с точным 
сопоставлением параметров; если такая есть, вызвать ее. 
[3] Попробовать правила разрешения для обычных функций ($$r13.2); если функция найдена по 
этим правилам, вызвать ее, иначе вызов является ошибкой. 
В любом случае, если на первом шаге найдено более одной функции, вызов считается неоднозначным 
и является ошибкой. Например: 
template 
T max(T a, T b) { return a>b?a:b; }; 
void f(int a, int b, char c, char d) 

int m1 = max(a,b); 
// max(int,int) 
char m2 = max(c,d); 
// max(char,char) 
int m3 = max(a,c); 
// ошибка: невозможно 
// 
создать max(int,char) 

Поскольку до генерации функции по шаблону не применяется никаких преобразований типа (правило 


Бьерн Страуструп.
Язык программирования С++ 
 
222 
[2]), последний вызов в этом примере нельзя разрешить как max(a,int(c)). Это может сделать сам 
пользователь, явно описав функцию max(int,int). Тогда вступает в силу правило [3]: 
template 
T max(T a, T b) { return a>b?a:b; } 
int max(int,int); 
void f(int a, int b, char c, char d) 

int m1 = max(a,b); // max(int,int) 
char m2 = max(c,d); // max(char,char) 
int m3 = max(a,c); // max(int,int) 

Программисту не нужно давать определение функции max(int,int), оно по умолчанию будет создано по 
шаблону. 
Можно определить шаблон max так, чтобы сработал первоначальный вариант нашего примера: 
template 
T1 max(T1 a, T2 b) { return a>b?a:b; }; 
void f(int a, int b, char c, char d) 

int m1 = max(a,b); 
// int max(int,int) 
char m2 = max(c,d); 
// char max(char,char) 
int m3 = max(a,c); 
// max(int,char) 

Однако, в С и С++ правила для встроенных типов и операций над ними таковы, что использовать 
подобный шаблон с двумя параметрами может быть совсем непросто. Так, может оказаться неверно 
задавать тип результата функции как первый параметр (T1), или, по крайней мере, это может привести 
к неожиданному результату, например для вызова 
max(c,i); // char max(char,int) 
Если в шаблоне для функции, которая может иметь множество параметров с различными 
арифметическими типами, используются два параметра, то в результате по шаблону будет 
порождаться слишком большое число определений разных функций. Более разумно добиваться 
преобразования типа, явно описав функцию с нужными типами. 


Достарыңызбен бөлісу:
1   ...   157   158   159   160   161   162   163   164   ...   256




©emirsaba.org 2024
әкімшілігінің қараңыз

    Басты бет