Д. Вандевурд, Н.М. Джосаттис - Шаблоны C++. Справочник разработчика (2003) (1160769), страница 22
Текст из файла (страница 22)
сешр1асе <Сурепаше Т, // Первый параметр // используется в т* Носе, // объявлении второго Еешр1аее<Т*> с1авв Вий> // и третьего параметров с1авв Яегпскигез Еешр1аее<еурепаше Т> с1авв Вох<Т>; Сешр1аке<сурепаше Т> чофй Сгапв1аее(Т*)з Сешр1асе<еурепаше Т> чозб Сгапв1асе<Т>(Т*); // ВЕРНО: первичный // шаблон // ОШИБКА // ВЕРНО: первичный // шаблон 8.2. Параметры шаблонов 125 8.2.1. Параметры типа Параметры типа задаются с помощью ключевых слов сурепаше либо с1авв; оба варианта эквивалентны . За ключевым словом должен следовать простой идена тнфикатор, за которым идет запятая, означающая начало следующего объявления параметра, закрывающая угловая скобка (>) для обозначения конца параметризованного выражения илн знак равенства (=) для обозначения начала заданного по умолчанию аргумента шаблона.
В пределах обьявления шаблона параметр типа ведет себя подобно имени, заданному с нанон/ью сурейеб. Например, нельзя использовать имя вида с1авв т, где т является параметром шаблона, даже если вместо т подставляется тип класса. сешр1аге <сурепаше А11осагог> с1авв Ь1вс ( с1авв А11осасог* а11осакогз // ОШИБКА Ег1епс) с1авв А11осасогг // ОШИБКА Вполне вероятно, что механизм, обеспечивающий возможность задавать такие объявления дружественных конструкций, появится в будущем. 82.2. Параметры, ие являющиеся типами Не являющиеся типами параметры — это константные значения, которые могут быть определены при компиляции или при компоновке . Тип такого параметра (другими слоз вами, тип значения, которое он обозначает) должен быль одним из следующих: ° целочисленный тип или тип перечисления; ° тнп указателя (вюпочая указатели на обычные объекты, функции и члены классов); ° ссылочный тип (как ссылки на объекты, так и ссылки на функции).
На сегодня все прочие типы в этот перечень не входят (хотя в будущем возможно включение в него типов с плавающей точкой; см. раздел 13.4, стр. 235). Возможно, это покажется несколько неожиданным„но объявление параметра шаблона, не являющегося типом, в некоторых случаях также может начинаться с ключевого слова сурепазве. 3 Ключевое слово с1авв не означает, что подставляемый параметр должен иметь тнп класса. тс может быть практически любой доступный твц.
Однако в качестве аргументов шаблона (независимых влв объявленных с помощью гурецкие нлв с1авв) нельзя использовать типы класса, которые опрелеляются в функции (локальные классы). з Шаблонные параметры шаблона также не обозначают типы, однако онв не рассматриваются а качестве параметров, не являющихся типами. 126 Глава 8. Вглубь шаблонов гевр1аге <гурепаве т, // Параметр типа гурепаве Т::А11осагог* А11осагог> // параметр, не // являющийся типом с1авв Ьйвсз гевр1аге <зпг ьий(5)> с1авв ьехегз // Реально зто 1пг* Севр1асе <Ьпс* Ьий> с1авв Ьехег; // ВЕРНО: повторное // объявление Параметры, не являющиеся типами.
объявляются почти так жс. как и переменные, но они не могут иметь спсцификаторов, таких, как всасйс, впсаЬ1е и т д. Возможно использование модификаторов сопев или уо1аг11е, но указание таких модификаторов у параметров внешнего уровня вложенности попросту игнорируется. гевр1асе <Ьпс сопла 1епоГЬ> с1авв Виггег; // Модификатор сопев здесь лишний Гевр1асе <1пс 1епдГЬ> с1авв Виййег; // Объявление аналогично предыдущему И наконец, параметры, не являющиеся типами, всегда являются ша(ие. Их' адрес нельзя получить, и им нельзя ничего присвоить. 8.2.3.
Шаблонные параметры шаблона Такие параметры являются символами-заполнителями для шаблонов классов. Они объявляются во многом подобно шаблонам классов, однако при этом нельзя использовать ключевые слова есгпсг и ипйоп. // ВЕРНО гевр1асе <Гевр1асе<сурепаве Х> с1авв С> чойс( б(С<1пс>* р); гевр1аге <севр1аге<сурепаве х> вггпсг .с> // ОшиБкА: чоЫ Й (С<1пг>* р); // вггисг здесь // не допускается гевр1аге <Гевр1асе<сурепаве Х> ип1оп С> нойс( г(С<1пг>* р); // ОШИБКА: // ипйоп здесь // не допускается В области видимости своих объявлений шаблонные параметры шаблонов использу' ются точно так жс, как и другие шаблоны класса.
Разницу здесь увидеть легко: в первом случае за ключевым словом следует простой идентификатор, а во втором — полное имл (другими словами, имя, содержащее два двоеточия, —:: ). В разделах 5.1, стр. 65, и 9.3.2, стр. 154, объясняется необходимость ключевого слова гурепаве в параметре, не являющемся типом. Возможно использование типов функций и массивов, но они неявно сводятся к типу соответствующего указателя. 8.2. Параметры шаблонов 127 Параметры шаблонных параметров шаблонов могут иметь аргументы, заданные по умолчанию.
Эти аргументы применяются в том случае, когда при использовании шаблонного параметра шаблона соответствующие параметры не указаны. Сешр1асе <Гешр1аее<сурепаше Т, Гурепаше А = МуА11осасог > с1авв Сопсайпег> с1авв Адарсасеоп ( Сопсаепег<1пг> згогаде; // Неявно эквивалентен // Сопса1пег<Т,МуА11осасог> Имя параметра шаблонного параметра шаблона может использоваться только в объявлениях других параметров данного шаблонного параметра шаблона. Это утверждение иллюстрируется на примере приведенного ниже (несколько искусственного) шаблона.
Сешр1асе <Гешр1асе<гурепаше Т, Т*> с1авв Виб> с1авв Ьехег ( вгас1с сЬаг вгогаде(5]; Вий<сЬаг, йЬехег<Ьий>::згогаде> Ьпйу ); сешр1аее <Сешр1асе<сурепаше Т> с1авв Ьевс> с1авв Мойе ( веасес Т* вгогаде; // ОШИБКА: параметр шаблонного // параметра шаблона здесь // использовать нельзя Однако обычно имена параметров шаблонного параметра шаблона не используются, н поэтому им зачастую вообще не присваиваются имена. Например, рассмотренный выше шаблон Абаргасеоп можно объявить следующим образом: сешр1асе <сешр1асе<сурепаше, сурепаше = МуА11осасог> с1авв Сопеаепег> с1авв Абарсас1оп ( сопгаепег<1пс> вгогаде1 // неявно эквивалентно // Сопсаепег<епг,МуА11осасог> 8 2.4.
Аргументы шаблона, задаваемые по умолчанию В настоящее время аргументы шаблона, задаваемые по умолчанию, допускаются только для объявлений шаблонов классов (см. раздел 13.3, стр. 233). Аргументом по 128 Глава 8. Вглубь шаблонов умолчанию может быть снабжен параметр шаблона любого типа (но при этом аргумент по умолчанию должен соответствовать "своему" параметру). Очевидно, что аргумент, заданный по умолчанию, не должен зависеть от собственного параметра, однако он может зависеть от предшествующих ему параметров. Севр1аге<курепаве Т, Сурепаве А11осаког = а11осаеог<Т» с1авв айве; Так же как и задаваемые по умолчанию аргументы функций, параметры шаблона могут иметь аргумент по умолчанию только в случае, когда аргументамн по умолчанию снабжены также и все последующие параметры. Последующие значения по умолчанию обычно указываются в том же объявлении шаблона, но они могут также быть обьявлены в предыдущих объявлениях этого шаблона Сказанное поясняет приведенный ниже пример.
Севр1аее<еурепаве Т1, сурепаве Т2, Сурепаве ТЗ,, Сурепаве Т4 = с)заг, Сурепаве Т5 = с)таг> с1авв Оийпеир1ез //ВЕРНО севр1асе<сурепаве Т1, сурепаве Т2, сурепаве ТЗ = с)таг, Сурепаве Т4, Сурепаве Т5> с1авв Оийпкпр1е; //ВЕРНО: Т4 и Т5 уже имеют // значения по умолчанию севр1асе<сурепаве Т1 = с)таг, сурепаве Т2, сурепаве ТЗ, Сурепаве Т4, Сурепаве Т5> с1авв Ои1пспр1е; //ОШИБКА: Т1 не может иметь аргумент ' // по умолчанию, поскольку у Т2 // его нет Задаваемые по умолчанию аргументы шаблона не могут повторяться.
севр1аее<еурепаве Т = чоЫ> с1авв ча1пе; Севр1аге<гурепаве Т = чоЫ> с1авв ча1ие; // ОШИБКА: повторяется // аргумент по умолчанию 8.3. Аргументы шаблонов Аргументы шаблонов — это значения, которые подставляются вместо параметров шаблона при инстанцировании шаблона. Такие значения можно задавать несколькими способами. ° Явные аргументы шаблона: за именем шаблона могут следовать явно указанные значения аргументов шаблона, заключенные в угловые скобки. Полученное в Ре зультате имя называется идентификатором шаблона ((ешр!аге.)д).
° Введенное имя класса: в области видимости шаблона класса К с параметрами шаблона Р1, Р2,... имя этого шаблона (х) может быть эквивалентно илентифи- 8.3. Аргументы шаблонов 129 катору шаблона Х<Р1, Р2, ... >. Более подробно это разъясняется в разделе 9.2.3, стр. 150. ° Аргументы шаблона, заданные по умолчанию: при наличии таких аргументов явно указанные аргументы шаблона в экземплярах шаблонов классов могут быть пропущены. Однако, даже если все параметры шаблона имеют значения по умолчанию, все равно должны быть указаны (возможно, пустые) угловые скобки.
° Вывод аргументов: аргументы шаблонов функций, не укаэанные явно, могут быть получены путем вывода из типов аргументов вызова функции в ее вызове. Более подробно это описано в главе 11, "Вывод аргументов шаблонов". Вывод осуществляется и в некоторых других ситуациях. Если все аргументы шаблона могут быть получены путем вывода, указывать угловые скобки после имени шаблона функции не требуется.