Π§ΠΈΡ‚Π°ΠΉΡ‚Π΅ ΠΊΠ½ΠΈΠ³ΠΈ ΠΎΠ½Π»Π°ΠΉΠ½ Π½Π° Bookidrom.ru! БСсплатныС ΠΊΠ½ΠΈΠ³ΠΈ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΊΠ»ΠΈΠΊΠ΅

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«Π―Π·Ρ‹ΠΊ программирования C++. ΠŸΡΡ‚ΠΎΠ΅ ΠΈΠ·Π΄Π°Π½ΠΈΠ΅Β». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 220

Автор Π‘Ρ‚Π΅Π½Π»ΠΈ Π›ΠΈΠΏΠΏΠΌΠ°Π½

16.1. ΠžΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ шаблона

ΠŸΡ€Π΅Π΄ΠΏΠΎΠ»ΠΎΠΆΠΈΠΌ, Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Π½Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ, которая сравниваСт Π΄Π²Π° значСния ΠΈ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚, являСтся Π»ΠΈ ΠΏΠ΅Ρ€Π²ΠΎΠ΅ ΠΈΠ· Π½ΠΈΡ… мСньшим, Ρ€Π°Π²Π½Ρ‹ΠΌ ΠΈΠ»ΠΈ большим, Ρ‡Π΅ΠΌ Π²Ρ‚ΠΎΡ€ΠΎΠ΅. ЀактичСски придСтся ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ нСсколько Ρ‚Π°ΠΊΠΈΡ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ, каТдая ΠΈΠ· ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… смоТСт ΡΡ€Π°Π²Π½ΠΈΠ²Π°Ρ‚ΡŒ значСния ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠ³ΠΎ Ρ‚ΠΈΠΏΠ°. На ΠΏΠ΅Ρ€Π²ΠΎΠΌ этапС ΠΌΠΎΠΆΠ½ΠΎ Π±Ρ‹Π»ΠΎ Π±Ρ‹ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ нСсколько ΠΏΠ΅Ρ€Π΅Π³Ρ€ΡƒΠΆΠ΅Π½Π½Ρ‹Ρ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ.

// Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ 0, Ссли значСния Ρ€Π°Π²Π½Ρ‹, -1, Ссли v1 мСньшС, ΠΈ 1,

// Ссли мСньшС v2

int compare(const string &v1, const string &v2) {

 if (v1 < v2) return -1;

 if (v2 < v1) return 1;

 return 0;

}

int compare(const double &v1, const double &v2) {

 if (v1 < v2) return -1;

 if (v2 < v1) return 1;

 return 0;

}

Π­Ρ‚ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΏΠΎΡ‡Ρ‚ΠΈ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ‡Π½Ρ‹ ΠΈ ΠΎΡ‚Π»ΠΈΡ‡Π°ΡŽΡ‚ΡΡ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‚ΠΈΠΏΠΎΠΌ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ². Π’Π΅Π»Π° Ρƒ ΠΎΠ±Π΅ΠΈΡ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ ΠΎΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²Ρ‹.

ΠŸΠΎΠ²Ρ‚ΠΎΡ€Π΅Π½ΠΈΠ΅ Ρ‚Π΅Π»Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ сравниваСмого Ρ‚ΠΈΠΏΠ° Π½Π΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΡƒΡ‚ΠΎΠΌΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ, Π½ΠΎ ΠΈ ΠΏΠΎΠ²Ρ‹ΡˆΠ°Π΅Ρ‚ Π²Π΅Ρ€ΠΎΡΡ‚Π½ΠΎΡΡ‚ΡŒ возникновСния ошибок. Однако Π²Π°ΠΆΠ½Π΅ΠΉ всСго Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ Π² этом случаС Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Π·Π°Ρ€Π°Π½Π΅Π΅ Π·Π½Π°Ρ‚ΡŒ всС Ρ‚ΠΈΠΏΡ‹, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ придСтся ΡΡ€Π°Π²Π½ΠΈΠ²Π°Ρ‚ΡŒ. Π­Ρ‚ΠΎΡ‚ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ Π½Π΅ сработаСт Π² случаС, ΠΊΠΎΠ³Π΄Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ прСдполагаСтся ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ для Ρ‚ΠΈΠΏΠΎΠ², нСизвСстных Π½Π° Π΄Π°Π½Π½Ρ‹ΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ‚.

16.1.1. Π¨Π°Π±Π»ΠΎΠ½Ρ‹ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ

ВмСсто Ρ‚ΠΎΠ³ΠΎ Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΡΡ‚ΡŒ Π½ΠΎΠ²ΡƒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ Ρ‚ΠΈΠΏΠ°, ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ шаблон Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ (function template). Π¨Π°Π±Π»ΠΎΠ½ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ β€” это ΠΏΡ€ΠΎΠ΅ΠΊΡ‚, ΠΏΠΎ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌΡƒ ΠΌΠΎΠΆΠ½ΠΎ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ Π½Π΅ΠΊΡƒΡŽ Π²Π΅Ρ€ΡΠΈΡŽ Π΄Π°Π½Π½ΠΎΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, ΡΠΏΠ΅Ρ†ΠΈΡ„ΠΈΡ‡Π΅ΡΠΊΡƒΡŽ для Π·Π°Π΄Π°Π½Π½ΠΎΠ³ΠΎ Ρ‚ΠΈΠΏΠ°. Π¨Π°Π±Π»ΠΎΠ½ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ compare() ΠΌΠΎΠΆΠ΅Ρ‚ Π²Ρ‹Π³Π»ΡΠ΄Π΅Ρ‚ΡŒ Ρ‚Π°ΠΊ:

template <typename Π’>

int compare(const T &v1, const T &v2) {

 if (v1 < v2) return -1;

 if (v2 < v1) return 1;

 return 0;

}

ΠžΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ шаблона начинаСтся с ΠΊΠ»ΡŽΡ‡Π΅Π²ΠΎΠ³ΠΎ слова template, Π·Π° ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌ слСдуСт раздСляСмый запятыми ΠΈ Π·Π°ΠΊΠ»ΡŽΡ‡Π΅Π½Π½Ρ‹ΠΉ Π² ΡƒΠ³Π»ΠΎΠ²Ρ‹Π΅ скобки (<>) список ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² шаблона (template parameter list), ΠΎΠ΄ΠΈΠ½ ΠΈΠ»ΠΈ нСсколько ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² шаблона (template parameter).

Бписок ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² Π² ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠΈ шаблона Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ пустым

Бписок ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² шаблона ΠΎΡ‡Π΅Π½ΡŒ ΠΏΠΎΡ…ΠΎΠΆ Π½Π° список ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ. Бписок ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π·Π°Π΄Π°Π΅Ρ‚ ΠΈΠΌΠ΅Π½Π° ΠΈ Ρ‚ΠΈΠΏΡ‹ Π»ΠΎΠΊΠ°Π»ΡŒΠ½Ρ‹Ρ… ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ…, Π½ΠΎ оставляСт ΠΈΡ… Π½Π΅ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΌΠΈ. Π˜Π½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² Π²ΠΎ врСмя выполнСния ΠΎΠ±Π΅ΡΠΏΠ΅Ρ‡ΠΈΠ²Π°ΡŽΡ‚ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Ρ‹.

Аналогично ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ шаблона ΠΏΡ€Π΅Π΄ΡΡ‚Π°Π²Π»ΡΡŽΡ‚ Ρ‚ΠΈΠΏΡ‹ ΠΈΠ»ΠΈ значСния, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹Π΅ ΠΏΡ€ΠΈ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠΈ класса ΠΈΠ»ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ. ΠŸΡ€ΠΈ использовании шаблона Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ (явно ΠΈΠ»ΠΈ нСявно) ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Ρ‹ шаблона (template argument), Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡΠ²ΡΠ·Π°Ρ‚ΡŒ ΠΈΡ… с ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΌΠΈ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π°ΠΌΠΈ шаблона.

НапримСр, рассматриваСмая функция compare() ΠΎΠ±ΡŠΡΠ²Π»ΡΠ΅Ρ‚ СдинствСнный ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ Ρ‚ΠΈΠΏΠ° Π’. Π’ шаблонС compare имя Π’ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ‚Π°ΠΌ, Π³Π΄Π΅ Π΄ΠΎΠ»ΠΆΠ½ΠΎ Π±Ρ‹Ρ‚ΡŒ Π½Π°Π·Π²Π°Π½ΠΈΠ΅ Ρ‚ΠΈΠΏΠ° Π΄Π°Π½Π½Ρ‹Ρ…. ЀактичСский Ρ‚ΠΈΠΏ Π’ Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ компилятором Π½Π° основании способа примСнСния Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ.

Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ экзСмпляра шаблона Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ

Когда происходит Π²Ρ‹Π·ΠΎΠ² шаблона Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, для Π²Ρ‹Π²ΠΎΠ΄Π° Ρ‚ΠΈΠΏΠΎΠ² Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ² шаблона компилятор ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Ρ‹ Π²Ρ‹Π·ΠΎΠ²Π°. Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, ΠΊΠΎΠ³Π΄Π° происходит Π²Ρ‹Π·ΠΎΠ² шаблона compare, компилятор ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ Ρ‚ΠΈΠΏ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ² для опрСдСлСния Ρ‚ΠΈΠΏΠ°, связанного с ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠΌ шаблона Π’. Рассмотрим ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ Π²Ρ‹Π·ΠΎΠ²:

cout << compare(1, 0) << endl; // Π’ - Ρ‚ΠΈΠΏ int

Π—Π΄Π΅ΡΡŒ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ ΠΈΠΌΠ΅Π΅Ρ‚ Ρ‚ΠΈΠΏ int. ΠšΠΎΠΌΠΏΠΈΠ»ΡΡ‚ΠΎΡ€ Π²Ρ‹Π²Π΅Π΄Π΅Ρ‚ ΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ Ρ‚ΠΈΠΏ int ΠΊΠ°ΠΊ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ шаблона, Π° Ρ‚Π°ΠΊΠΆΠ΅ свяТСт этот Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ с ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠΌ Π’ шаблона.

ΠŸΡ€ΠΈ создании экзСмпляра (instantiation) спСцифичСской вСрсии Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ компилятор сам ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ Π²Ρ‹Π²Π΅Π΄Π΅Π½Π½Ρ‹Π΅ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ шаблона. ΠŸΡ€ΠΈ этом ΠΎΠ½ подставляСт фактичСскиС Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Ρ‹ шаблона вмСсто ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΡ… ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² шаблона. Рассмотрим ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ Π²Ρ‹Π·ΠΎΠ²:

// созданиС экзСмпляра int compare(const int&, const int&)

cout << compare(1, 0) << endl; // T - Ρ‚ΠΈΠΏ int

// созданиС

// экзСмпляра int compare(const vector<int>&, const vector<int>&)

vector<int> vec1{1, 2, 3}, vec2{4, 5, 6};

cout << compare(vec1, vec2) << endl; // T - Ρ‚ΠΈΠΏ vector<int>

Π—Π΄Π΅ΡΡŒ компилятор создаСт Π΄Π²Π° экзСмпляра Ρ€Π°Π·Π½Ρ‹Ρ… вСрсий Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ compare(). Π’ ΠΏΠ΅Ρ€Π²ΠΎΠΉ ΠΈΠ· Π½ΠΈΡ… ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ Π’ Π·Π°ΠΌΠ΅Π½Π΅Π½ Ρ‚ΠΈΠΏΠΎΠΌ int.

int compare(const int &v1, const int &v2) {

 if (v1 < v2) return -1;

 if (v2 < v1) return 1;

 return 0;

}

Π’ΠΎ Π²Ρ‚ΠΎΡ€ΠΎΠΌ Π²Ρ‹Π·ΠΎΠ²Π΅ создаСтся вСрсия Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ compare() с ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠΌ Π’, Π·Π°ΠΌΠ΅Π½Π΅Π½Π½Ρ‹ΠΌ Ρ‚ΠΈΠΏΠΎΠΌ vector<int>. Π’Π°ΠΊΠΎΠ΅ созданиС компилятором Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ ΠΈ Π½Π°Π·Ρ‹Π²Π°ΡŽΡ‚ созданиСм экзСмпляра шаблона.

ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ Ρ‚ΠΈΠΏΠ° шаблона

Π£ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ compare() Π΅ΡΡ‚ΡŒ ΠΎΠ΄ΠΈΠ½ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ Ρ‚ΠΈΠΏΠ° (type parameter) шаблона. Как ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ, ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ Ρ‚ΠΈΠΏΠ° ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΊΠ°ΠΊ спСцификатор Ρ‚ΠΈΠΏΠ° Ρ‚Π°ΠΊΠΈΠΌ ΠΆΠ΅ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, ΠΊΠ°ΠΊ ΠΈ встроСнный спСцификатор Ρ‚ΠΈΠΏΠ° ΠΈΠ»ΠΈ класса. Π’ частности, ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ Ρ‚ΠΈΠΏΠ° ΠΏΡ€ΠΈΠΌΠ΅Π½ΠΈΠΌ ΠΏΡ€ΠΈ Π½Π°Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΈ Ρ‚ΠΈΠΏΠ° Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΠΎΠ³ΠΎ значСния ΠΈΠ»ΠΈ Ρ‚ΠΈΠΏΠ° ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, Π° Ρ‚Π°ΠΊΠΆΠ΅ Π² ΠΎΠ±ΡŠΡΠ²Π»Π΅Π½ΠΈΡΡ… ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… ΠΈΠ»ΠΈ привСдСниях Π² Ρ‚Π΅Π»Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ:

// ok: для Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΠΎΠ³ΠΎ значСния ΠΈ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ Ρ‚ΠΎΡ‚ ΠΆΠ΅ Ρ‚ΠΈΠΏ

template <typename Π’> Π’ foo(Π’* p) {

 Π’ tmp = *p; // Ρ‚ΠΈΠΏ tmp совпадаСт с Ρ‚ΠΈΠΏΠΎΠΌ, Π½Π° ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ p

 // ...

 return tmp;

}

ΠšΠ°ΠΆΠ΄ΠΎΠΌΡƒ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρƒ Ρ‚ΠΈΠΏΠ° Π΄ΠΎΠ»ΠΆΠ½ΠΎ ΠΏΡ€Π΅Π΄ΡˆΠ΅ΡΡ‚Π²ΠΎΠ²Π°Ρ‚ΡŒ ΠΊΠ»ΡŽΡ‡Π΅Π²ΠΎΠ΅ слово class ΠΈΠ»ΠΈ typename:

// ошибка: U Π΄ΠΎΠ»ΠΆΠ½ΠΎ ΠΏΡ€Π΅Π΄ΡˆΠ΅ΡΡ‚Π²ΠΎΠ²Π°Ρ‚ΡŒ Π»ΠΈΠ±ΠΎ typename, Π»ΠΈΠ±ΠΎ class

template <typename Π’, U> Π’ calc(const T&, const U&);

Π’ спискС ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² шаблона эти ΠΊΠ»ΡŽΡ‡Π΅Π²Ρ‹Π΅ слова ΠΈΠΌΠ΅ΡŽΡ‚ ΠΎΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²Ρ‹ΠΉ смысл ΠΈ ΠΏΡ€ΠΈΠΌΠ΅Π½ΡΡŽΡ‚ΡΡ взаимозамСняСмо. Оба ΠΊΠ»ΡŽΡ‡Π΅Π²Ρ‹Ρ… слова ΠΏΡ€ΠΈΠΌΠ΅Π½ΠΈΠΌΡ‹ ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ:

// ok: Π² спискС ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² шаблона Π½Π΅Ρ‚ Π½ΠΈΠΊΠ°ΠΊΠΎΠΉ Ρ€Π°Π·Π½ΠΈΡ†Ρ‹ ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΊΠ»ΡŽΡ‡Π΅Π²Ρ‹ΠΌΠΈ

// словами typename и class

template <typename Π’, class U> calc(const T&, const U&);

Для обозначСния ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° Ρ‚ΠΈΠΏΠ° шаблона ΠΈΠ½Ρ‚ΡƒΠΈΡ‚ΠΈΠ²Π½ΠΎ понятнСй ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΊΠ»ΡŽΡ‡Π΅Π²ΠΎΠ΅ слово typename, Π° Π½Π΅ class; Π² ΠΊΠΎΠ½Ρ†Π΅ ΠΊΠΎΠ½Ρ†ΠΎΠ², для фактичСского Ρ‚ΠΈΠΏΠ° ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° Π²ΠΏΠΎΠ»Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ использован встроСнный Ρ‚ΠΈΠΏ, Π° Π½Π΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ класс. ΠšΡ€ΠΎΠΌΠ΅ Ρ‚ΠΎΠ³ΠΎ, ΠΊΠ»ΡŽΡ‡Π΅Π²ΠΎΠ΅ слово typename Π±ΠΎΠ»Π΅Π΅ Ρ‚ΠΎΡ‡Π½ΠΎ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ Π½Π° Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π΅ Π·Π° Π½ΠΈΠΌ имя ΠΏΡ€ΠΈΠ½Π°Π΄Π»Π΅ΠΆΠΈΡ‚ Ρ‚ΠΈΠΏΡƒ. Однако ΠΊΠ»ΡŽΡ‡Π΅Π²ΠΎΠ΅ слово typename Π±Ρ‹Π»ΠΎ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΎ Π² язык Π‘++ ΠΊΠ°ΠΊ Ρ‡Π°ΡΡ‚ΡŒ стандарта Π‘++, поэтому Π² ΡƒΡΡ‚Π°Ρ€Π΅Π²ΡˆΠΈΡ… ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ°Ρ…, вСроятнСС всСго, ΠΎΡΡ‚Π°Π»ΠΎΡΡŒ ΠΈΡΠΊΠ»ΡŽΡ‡ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ΠΊΠ»ΡŽΡ‡Π΅Π²ΠΎΠ΅ слово class.

ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ значСния шаблона

ΠšΡ€ΠΎΠΌΠ΅ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² Ρ‚ΠΈΠΏΠ°, Π² ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠΈ шаблона ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Π½Ρ‹ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ значСния (nontype parameter). ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ значСния прСдставляСт Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, Π° Π½Π΅ Ρ‚ΠΈΠΏ. ΠŸΡ€ΠΈ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠΈ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² значСния вмСсто ΠΊΠ»ΡŽΡ‡Π΅Π²ΠΎΠ³ΠΎ слова class ΠΈΠ»ΠΈ typename ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ ΠΈΠΌΠ΅Π½Π° Ρ‚ΠΈΠΏΠΎΠ².

ΠŸΡ€ΠΈ создании экзСмпляра шаблона Ρ‚Π°ΠΊΠΈΠ΅ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ Π·Π°ΠΌΠ΅Π½ΡΡŽΡ‚ΡΡ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ΠΌ, прСдоставлСнным ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΌ ΠΈΠ»ΠΈ Π²Ρ‹Π²Π΅Π΄Π΅Π½Π½Ρ‹ΠΌ компилятором. Π§Ρ‚ΠΎΠ±Ρ‹ компилятор смог ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ экзСмпляр шаблона Π²ΠΎ врСмя компиляции, эти значСния Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π±Ρ‹Ρ‚ΡŒ константными выраТСниями (см. Ρ€Π°Π·Π΄Π΅Π» 2.4.4).

Π’ качСствС ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° напишСм Π²Π΅Ρ€ΡΠΈΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ compare(), Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‰ΡƒΡŽ со строковыми Π»ΠΈΡ‚Π΅Ρ€Π°Π»Π°ΠΌΠΈ. Π’Π°ΠΊΠΈΠ΅ Π»ΠΈΡ‚Π΅Ρ€Π°Π»Ρ‹ ΠΏΡ€Π΅Π΄ΡΡ‚Π°Π²Π»ΡΡŽΡ‚ собой массивы Ρ‚ΠΈΠΏΠ° const char. ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΡΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ массив нСльзя, ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΠΌ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ ΠΊΠ°ΠΊ ссылки Π½Π° массив (Ρ€Π°Π·Π΄Π΅Π» 6.2.4). ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠ° Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ ΡΡ€Π°Π²Π½ΠΈΠ²Π°Ρ‚ΡŒ Π»ΠΈΡ‚Π΅Ρ€Π°Π»Ρ‹ Ρ€Π°Π·Π½Ρ‹Ρ… Π΄Π»ΠΈΠ½, снабдим шаблон двумя ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π°ΠΌΠΈ значСния. ΠŸΠ΅Ρ€Π²Ρ‹ΠΉ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ шаблона прСдставляСт Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΏΠ΅Ρ€Π²ΠΎΠ³ΠΎ массива, Π° Π²Ρ‚ΠΎΡ€ΠΎΠΉ β€” Ρ€Π°Π·ΠΌΠ΅Ρ€ Π²Ρ‚ΠΎΡ€ΠΎΠ³ΠΎ:

template<unsigned N, unsigned M>

int compare(const char (&p1)[N], const char (&p2)[M]) {

 return strcmp(p1, p2);

}

ΠŸΡ€ΠΈ Π²Ρ‹Π·ΠΎΠ²Π΅ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΉ вСрсии Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ compare() компилятор Π±ΡƒΠ΄Π΅Ρ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ€Π°Π·ΠΌΠ΅Ρ€ Π»ΠΈΡ‚Π΅Ρ€Π°Π»ΠΎΠ² для создания экзСмпляра шаблона с Ρ€Π°Π·ΠΌΠ΅Ρ€Π°ΠΌΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌΠΈ Π·Π°ΠΌΠ΅Π½ΡΡŽΡ‚ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ N ΠΈ M:

compare("hi", "mom")

НС Π·Π°Π±Ρ‹Π²Π°ΠΉΡ‚Π΅, Ρ‡Ρ‚ΠΎ компилятор Π·Π°Π²Π΅Ρ€ΡˆΠ°Π΅Ρ‚ строковый Π»ΠΈΡ‚Π΅Ρ€Π°Π» пустым символом (см. Ρ€Π°Π·Π΄Π΅Π» 2.1.3). Π’ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π΅ компилятор создаст Ρ‚Π°ΠΊΠΎΠΉ экзСмпляр:

int compare(const char (&p1)[3], const char (&p2)[4])

ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ значСния ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ цСлочислСнным Ρ‚ΠΈΠΏΠΎΠΌ, ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΌ, ссылкой Π½Π° ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ (l-Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ΠΌ) ΠΈΠ»ΠΈ Π½Π° Ρ‚ΠΈΠΏ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ. АргумСнт, связанный с цСлочислСнным ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠΌ значСния, Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ константным Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ΠΌ. Π£ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ², привязанных ΠΊ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŽ ΠΈΠ»ΠΈ ссылочному ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρƒ значСния, Π΄ΠΎΠ»ΠΆΠ½Π° Π±Ρ‹Ρ‚ΡŒ статичСская ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ сущСствования (см. Π³Π»Π°Π²Ρƒ 12). НСльзя ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΎΠ±Ρ‹Ρ‡Π½Ρ‹ΠΉ (нСстатичСский) Π»ΠΎΠΊΠ°Π»ΡŒΠ½Ρ‹ΠΉ ΠΈΠ»ΠΈ динамичСский ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΠΊΠ°ΠΊ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ шаблона для ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° значСния шаблона Π² Π²ΠΈΠ΄Π΅ ссылки ΠΈΠ»ΠΈ указатСля. ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€-ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Ρ‚Π°ΠΊΠΆΠ΅ создан ΠΊΠ°ΠΊ nullptr ΠΈΠ»ΠΈ Π½ΡƒΠ»Π΅Π²ΠΎΠ΅ константноС Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅.