|
Программирование >> Инициализация объектов класса, структура
---------max.h------- обобщенное определение шаблона template <class Type> Type max( Type t1, Type t2 ) { /* ... */ } объявление явной специализации шаблона для const char* typedef const char *PCC; template<> PCC max< PCC >( PCC s1, PCC s2 ); ---------File1.C------- #include <iostream> #include max.h void another() ; int main() { специализация const char* max< const char* >( const char*, const char* ); const char *p = max( hello , world ); .... которых используется шаблон max() : Упражнение 10.10 Определите шаблон функции count() для подсчета числа появлений некоторого значения в массиве. Напишите вызывающую программу. Последовательно передайте в ней массив значений типа double, int и сhar. Напишите специализированный экземпляр шаблона count() для обработки строк. 10.7. Перегрузка шаблонов функций А Шаблон функции может быть перегружен. В следующем примере есть три перегруженных объявления для шаблона min() : специализация, и при обращении к max( hi , again ) именно она и вызывается. Поскольку в одной и той же программе функция max(const char*, const char*) то конкретизируется по шаблону, то специализируется явно, компилятор считает программу некорректной. Для исправления этого объявление явной специализации шаблона должно предшествовать вызову функции miax(const char*, const char*) в файле File1.C. Чтобы избежать таких ошибок и гарантировать, что объявление явной специализации шаблона max(const char*, const char*) внесено в каждый файл, где используется шаблон функции max() с аргументами типа const char*, это объявление следует поместить в заголовочный файл max.h и включать его во все исходные файлы, в определение шаблона класса Array ( см. раздел 2.4) template <typename Type> class Array( /* ... */ }; три объявления шаблона функции min() template <typename Type> Type min( const Array<Type>&, int ); #1 template <typename Type> Type min( const Type*, int ); #2 template <typename Type> Type min( Type, Type ); #3 Следующее определение main() иллюстрирует, как могут вызываться три объявленных #include <cmath> int main() { Array<int> iA(1024); конкретизация класса int ia[1024]; Type == int; min( const Array<int>&, int ) int ivalO = min( i, 1024 ); Type == int; min( const int*, int ) int ival1 = min( ia, 1024 ); Type == double; min( double, double ) double dval0 = min( sqrt( i[0] ), sqrt( ia[0] ) ); return 0; таким образом функции: Разумеется, тот факт, что три перегруженных шаблона функции успешно объявлены, не означает, что они могут быть также успешно вызваны. Такие шаблоны могут приводить к неоднозначности при вызове конкретизированного шаблона. Например, для следующего template <typename T> определения шаблона miin5() int min5( T, T ) { /* ... */ } функция не конкретизируется по шаблону, если min5() вызывается с аргументами разных типов; при этом процесс вывода заканчивается с ошибкой, поскольку из фактических аргументов функции выводятся два разных типа для T. правильно: int min5( int, usigned int ) При следующем обращении производится конкретизация этого шаблона функции: min5( i, ui ); ошибка: неоднозначность: две возможн конкретизации из min5( T, T ) и min5( T, U ) К сожалению, теперь стал неоднозначным предыдущий вызов: min5( 1024, i ); Второе объявление min5() допускает наличие у функции аргументов различных типов, но не требует этого. В нашем случае и T, и U типа int. Оба объявления шаблонов могут быть конкретизированы вызовом, в котором два аргумента функции имеют один и тот же тип. Единственный способ указать, какой шаблон более предпочтителен, устранив тем самым неоднозначность, - явно задать его аргументы. (О явном задании аргументов правильно: конкретизация из min5( T, U ) шаблона см. раздел 10.4.) Например: min5<int, int>( 1024, i ); Однако в этом случае мы можем обойтись без перегрузки шаблона функции. Поскольку шаблон min5(T,U) подходит для всех вызовов, для которых подходит min5(T,T) , то одного объявления min5(T,U) вполне достаточно, а объявление min5(T,T) можно удалить. М1 уже говорили в главе 9, что, хотя перегрузка допускается, при проектировании таких функций надо быть внимательным и использовать ее только при необходимости. Те же соображения применимы и к определению перегруженных шаблонов. int i; unsigned int ui; правильно: для T веден тип int min5( 1024, i ); вод аргументов шаблона заканчивается с ошибкой: для T можно вести два разн типа min5 ( i, ui ); Для разрешения второго вызова можно было бы перегрузить min5() , допустив два template <typename T, typename U> различных типа аргументов: int min5( T, U );
|
© 2006 - 2025 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |