Г. Шилдт - Полный справочник по C++ (1109478), страница 72
Текст из файла (страница 72)
вшаратдя(х, у); // Вызов обобщенной функции вшаратдв(). яшаратдя(а, Ы; // Вызов обобщенной функции яшаратдь-() соцс « 'г!ереставленные значения 1, 3: " « 1 « ' " « 3 « 'м' соцх « "Переставленные значения х, у: « х « ' ' « у « * 1п' соцх « "Переставленные значения а, Ь: " « а « ' ' « Ь « ' 1п' тесихп 0; ) Зга программа выводит на экран следующие строки. Исходные значения 1, 3: 10 20 Исходные значения х, у: 10.1 23.3 Исходные значения а, Ь: х в Внутри специализации функции яыаратдя для целых чисел. Внутри шаблонной функции внарахдв. Внутри шаблонной функции яшарахдв. Переставленные значения 1, 3: 20 10 Переставленные значения х, у: 23.3 10.1 Переставленные значения а, Ь: в х Глава!8. Шаблоны Как указано в комментариях программы, при вызове функции виаракдв() активизируется сс явно перегруженная версия.
Таким образом, компилятор нс генерирует версию шаблонной функции выаракдв () . Недавно появилась новая синтаксическая конструкция, прсдназначснная для обозначения явной специализации функции. Этот метод используст ключсвос слово вешр1аье. Например, перегруженную функцию виаракдв() из прсдыдушсго примера можно переписать следующим образом. // Новая синтаксическая конструкция лля специализации. сетр1асе<> чогб виарагдв<апс>(звс аа, 1пс аЫ ( 1пс сешр; сгшр = а; а =Ь; Ь = секр; соне « "Внутри специализации функции выарагдв лля целых чисел. 1п": ) Как видим, новый способ опрелслсння специализации содержит конструкцию вешр1аве<>. Тип данных, для которо~о предназначена специализация, указывается внутри угловых скобок после имени функции. Для специализации любого другого типа обобщенной функции используется такая жс синтаксическая конструкция, В настоящее время оба способа определения специализации эквивалентны.
Вероятно, в будущем новый стиль может оказаться более предпочтительным. С помощью явной специализации шаблона можно настраивать версию обобщенной функции на конкретную ситуаци|о. Это позволяет максимально эффективно использовать сс для заданного типа данных. Олнако, как правило, если для разных типов данных требуются разные версии функции, слсдусг применять перегрузку, а нс шаблоны. Перегрузка шаблонной функции Для того чтобы перегрузить спецификацию обобщенной функции, достаточно создать сщс одну версию шаблона, огличающуюся от остальных своим списком параметров. // Перегрузка шаблонной функции. $1пс1цбе <говсгеазп> цвапд пашезрасе всд; // Первая версия шаблонной функции г() Сешр1аге <с1авз Х> ча1<) Й(Х а) ( соцв « "Внутри функции Г(Х а) 1п"; ) // Первая версия шаблонной функции х().
сешр1асе <с1авв х, с1авв т> чо10 Г(х а, у ы ( соцв « "Внутри функции г(Х а, У Ы 1п"; ) 1пс ша(п() ( Г(10); // Вывоз функции Е(Х). Г(10, 20); // Вызов функции Г(Х, У). Часть П. Язьж С++ Здесь шаблон функции е () перегружен для одного и двух параметров.
Использование стандартных параметров шаблонных функций При определении шаблонной функции можно смешивать с)внларт~)ыс и обобшснпые параметры. В этом слу ~ае станлартныс параметры ничем нс о~личаются от параметров любых других функций. Рассмотрим пример. // Применение стандарткых параметров в ыаблонной функции. аьпс1цс)е кьоветеаи> ивьпд патеврасе вес); сопят ьпт тявнтптН = В; // Выводит на экран данные в поэиции СаЬ.
сетр1асе<с1авв х> тово еаьоие(х с)аеа, упт еаЬ) ( сот(; ЕаЬ; ЕаЬ--) Гот(тпс т=0; т<тЛВИтПТН; 1~+) соце « соце « г)аса « "Хп"; ) тпс та1п(! гаЬОцт("Проверка", 0); СаЬОце(100, 1); ЕаЬОце('Х', 2)/ СаЬОце (10/3, 3); тесцтп О; Программа выводит на экран следуюшие сообшения. Проверка 100 х 3 В этой программе функция еаъоие() выводит на экран свой первый аргумент, позиция которого опрслеляется вторым параметром еаЬ. Псскольку первый аргумент имеет обобшенный тип, функция евьоце() может выводить на экран данные любого типа. Параметр Еаь является стандартным и передается по значению. Смешение обобшснных и стандартных параметров не вызывает никаких проблем и может оказаться полезным. Ограничения на обобщенные функции Обобшснные функции напоминают перегруженные, но на них налагаются еше более жесткис ограничения.
При перегрузке внутри тела каждой функции можно выполнять разные операции. В то жс время обобшенная функция должна выполнять одну и ту жс универсальную операцию для всех версий, различаться могут лишь типы ланных. Рассмотрим перегруженную функцию на слсдуюшем примере. Эти функции нельзя заменять обобшенными, поскольку они имеют разное прелназначение. Глава ) 8. Шаблоны З1пс1пбе <ьоеехеаи> атпс1ц<(е <стпа0» пяапд паиеарасе аеб; чоьб туГппс(1пе з.) ( сопя « "Значение = " « 1 « "1п"," ) чоьг] тутмос(г)оиЬ1е г(] бопЫе зпсрахс; с(опЫе 1гасрахс; Егасрахс = по<(х(г(, ььпсрахс]; сопс « "Дробная часть = " « бхасрагс; попс « "1п") соус « "целая гасть = " « 1псрахс; ) зпс таус() ( пугцпс(1); путипс(12.2)( хеспгп О; ~Й Применение обобщенных функций Возможность использовать обобщенные функции — одно из самых ценных свойств языка С++.
Их мож1ю применять н самых разных ситуациях. Как указывалось ранее, если функция описывает унинерсальный алгоритм, ес можно сделать шаблонной. После этого ее можно применять к любому типу данных. Прежде чем перейти к описанию шаблонных классон, рассмотрим дна примера обобщенных функций, демонстрирующих эффектна~ юсть и удобстно этого механизма. Обобщенная сортировка Сортиронка прсдстанляст собои типичный пример унинсрсального алгоритма.
Как правило, алгоритм сортировки сонершенно не занисит оз типа сортируемых данных Следующая программа лемопстрирует обобщенную функцию, предназначенную для сортировки данных методом пузырька Несмотря на то что этот алгоритм сортировки янлястся одним из самых медленных, он очень прост и нагляден.
Функция Ьпю>1в() упорядочивает массив любого типа. Ей передается указатель на первый элемент массина и количсстно элемснтон н массиве. // Обобыенная сортировка методом пузырька. З1пс1п((е <1оясхеат> пньпд паиеерасе нес(; Сеир1аее <с1аая Х> чорт( ЬцЬЫе( х *1сетя, // указатель на упорядочинаемый массин. 1пс соиле] // Количество элементов массива. гедзвсех 1п» а, Ьг Часть 1!. Язык С++ х е; йох(а=1; а<сопле; а++) бох(Ь=соипе-1; Ь»=а; Ь вЂ ) 11(1ееяе[Ь-1] > 1еемв[Ь]) // Перестановка элементов.
— 1хеыв[Ь-1]; 1ееыв[Ь-1] = 1сеыв!Ь]; 1хеыв[Ь] ) ) 1пс маьп() ( 1пс 1аххау[7] = (7, 5, 4, 3, 9, 8, б); е)оиЬ1е г)аххау[5] = (4.3, 2.5, -0.9, 100.2, 3.0); 1пс соцс « "Неупорядоченный массив целых чисел: Еох(1=-0; 1<7; 1++) соне « 1аххау[х] « соне « епг)1; соне « "Неупорядоченный массив действительных чисел: бох(1=0г х<5; 1++) соцс « е(аххау[1] « соцс « епе]1~ ЬцЬЬзе(1аххау, 7); ЬпЬЬ1е(с)аххау, 5); соне « "упорядоченный массив целых чисел: бох(1=0; 1<7; 1++) соне « 1аххау[х) « соцх « епг)1; сосс « "упорядоченный массия действительных чисел: бох(1=0; 1<5; 1++) соцс « с)аххау[1) « сопс « еп((1; хеецхп 0; ) Программа выводит на экран следующие результаты. Неупорядоченный массив целых чисел: 7 5 4 3 9 8 б Неупорядоченный массив действительных чисел: 4.3 2.5 -0.9 100.2 3 Упорядоченный массив целых чисел: 3 4 5 б 7 8 9 Упорядоченный массив действительных чисел: -0.9 2.5 3 4.3 100.2 Как видим, в программе создакпся два массива, имеющие соответственно типы 1пс И аооЬ1е.
Поскольку функция ЬоЬЬ1е() является шаблонной, она автоматически перегружается для каждого из этих типов. Эту функцию можно применить для сортировки данных другого типа, даже объектов какою-нибудь класса. Компилятор автоматически создаст соответствующую версию функции для нового типа. Глава 1В. Шаблоны Уплотнение массива Проиллзострирусм преимушества шаблонов на примере функции с<карасе(). Эта функция уплотняет элементы массива. Довольно часто приходится удалять несколько элементов из середины массива и перемешать оставшиеся элементы влево, заполняя образоваашузося пустоту. Эта операция носит универсальный характер и нс зависит от типа массива.
Обобшенная функция осирисе() получает указатель на первый элсмспз массива, количество его элементов, а также индексы первого и последнего элементов удаленного отрезка массива. За~ем функция удаляез. указанные элементы и уплотняет массив. Для иллюстрации неиспользуемые элементы, образуюшиеся при уплотнении массива, обнуляются, // оообиенная функция уплотненмя массива.
Мзпю1ице <зовсгеавз> цвьпд паязеврасе ведз Еевр1асе <с1авв Х> тоззг) соазрасс( х "ьеетв, // указатель ьа уоготняезагй массив. зпь сосне, // Количество элементов массива. зпе всагс, // Индекс первого удаленного элемента. 1пс елей // Индекс последнего удаленно~о элемента. геп[всет зпе зз гззг[з.-епс[ь)з з<соцпез 1++„ веаге++) зсепзв[веаге] = зеезлв[1]з /* для иллюстрации оставшаяся часть массива заполняется нулями.