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

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«Π­Ρ„Ρ„Π΅ΠΊΡ‚ΠΈΠ²Π½ΠΎΠ΅ использованиС C++. 55 Π²Π΅Ρ€Π½Ρ‹Ρ… способов ΡƒΠ»ΡƒΡ‡ΡˆΠΈΡ‚ΡŒ структуру ΠΈ ΠΊΠΎΠ΄ Π²Π°ΡˆΠΈΡ… ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΒ». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 62

Автор Π‘ΠΊΠΎΡ‚Ρ‚ ΠœΠ°ΠΉΠ΅Ρ€Ρ

Π’ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ΅ TR1 (см. ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ 54) Π΅ΡΡ‚ΡŒ Ρ†Π΅Π»Ρ‹ΠΉ ряд Π½ΠΎΠ²Ρ‹Ρ… классов-характСристик, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΏΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²Π»ΡΡŽΡ‚ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΎ Ρ‚ΠΈΠΏΠ°Ρ…, Π²ΠΊΠ»ΡŽΡ‡Π°Ρ is_fundamental<T> (Π³Π΄Π΅ T – встроСнный Ρ‚ΠΈΠΏ), is_array<T> (Π³Π΄Π΅ T – Ρ‚ΠΈΠΏ массива) ΠΈ is_base_of<T1,T2> (Ρ‚ΠΎ Π΅ΡΡ‚ΡŒ являСтся Π»ΠΈ T1 Ρ‚Π΅ΠΌ ΠΆΠ΅, Ρ‡Ρ‚ΠΎ ΠΈ T2, Π»ΠΈΠ±ΠΎ Π΅Π³ΠΎ Π±Π°Π·ΠΎΠ²Ρ‹ΠΌ классом). ВсСго TR1 добавляСт ΠΊ стандартному C++ Π±ΠΎΠ»Π΅Π΅ 50 классов-характСристик.

Π§Ρ‚ΠΎ слСдуСт ΠΏΠΎΠΌΠ½ΠΈΡ‚ΡŒ

β€’ ΠšΠ»Π°ΡΡΡ‹-характСристики Π΄Π΅Π»Π°ΡŽΡ‚ доступной ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΎ Ρ‚ΠΈΠΏΠ°Ρ… Π²ΠΎ врСмя компиляции. Они Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Ρ‹ с ΠΏΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ΠΌ шаблонов ΠΈ ΠΈΡ… спСциализаций.

β€’ Π’ сочСтании с ΠΏΠ΅Ρ€Π΅Π³Ρ€ΡƒΠ·ΠΊΠΎΠΉ классы-характСристики ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‚ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡΡ‚ΡŒ Ρ‚ΠΈΠΏΡ‹ Π²ΠΎ врСмя компиляции.

ΠŸΡ€Π°Π²ΠΈΠ»ΠΎ 48: Π˜Π·ΡƒΡ‡ΠΈΡ‚Π΅ ΠΌΠ΅Ρ‚Π°ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ шаблонов

ΠœΠ΅Ρ‚Π°ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ шаблонов (template metaprogramming – TMP) – это процСсс написания основанных Π½Π° ΡˆΠ°Π±Π»ΠΎΠ½Π°Ρ… ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌ Π½Π° C++, исполняСмых Π²ΠΎ врСмя компиляции. На ΠΌΠΈΠ½ΡƒΡ‚Ρƒ Π·Π°Π΄ΡƒΠΌΠ°ΠΉΡ‚Π΅ΡΡŒ ΠΎΠ± этом: шаблонная ΠΌΠ΅Ρ‚Π°ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° – это ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ°, написанная Π½Π° C++, которая исполняСтся Π²Π½ΡƒΡ‚Ρ€ΠΈ компилятора C+ +. Когда TMP-ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° Π·Π°Π²Π΅Ρ€ΡˆΠ°Π΅Ρ‚ исполнСниС, Π΅Π΅ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ – Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚Ρ‹ ΠΊΠΎΠ΄Π° Π½Π° C++, ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Π΅ ΠΈΠ· шаблонов, β€“ компилируСтся ΠΊΠ°ΠΊ ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ.

Если эта идСя Π½Π΅ ΠΏΠΎΡ€Π°Π·ΠΈΠ»Π° вас Π΄ΠΎ Π³Π»ΡƒΠ±ΠΈΠ½Ρ‹ Π΄ΡƒΡˆΠΈ, Π·Π½Π°Ρ‡ΠΈΡ‚, Π²Ρ‹ нСдостаточно напряТСнно Π΄ΡƒΠΌΠ°Π»ΠΈ ΠΎ Π½Π΅ΠΉ.

C++ Π½Π΅ прСдназначался для мСтапрограммирования шаблонов, Π½ΠΎ с Ρ‚Π΅Ρ… ΠΏΠΎΡ€, ΠΊΠ°ΠΊ тСхнология TMP Π±Ρ‹Π»Π° ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Π° Π² Π½Π°Ρ‡Π°Π»Π΅ 90-Ρ… Π³ΠΎΠ΄ΠΎΠ², ΠΎΠ½Π° оказалась Π½Π°ΡΡ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΠΎΠ»Π΅Π·Π½ΠΎΠΉ, Ρ‡Ρ‚ΠΎ, вСроятно, ΠΈ Π² сам язык, ΠΈ Π² ΡΡ‚Π°Π½Π΄Π°Ρ€Ρ‚Π½ΡƒΡŽ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΡƒ Π±ΡƒΠ΄ΡƒΡ‚ Π²ΠΊΠ»ΡŽΡ‡Π΅Π½Ρ‹ Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΡ, ΠΎΠ±Π»Π΅Π³Ρ‡Π°ΡŽΡ‰ΠΈΠ΅ Ρ€Π°Π±ΠΎΡ‚Ρƒ с TMP. Π”Π°, TMP Π±Ρ‹Π»ΠΎ ΠΈΠΌΠ΅Π½Π½ΠΎ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΎ, Π° Π½Π΅ ΠΏΡ€ΠΈΠ΄ΡƒΠΌΠ°Π½ΠΎ. БрСдства, Π»Π΅ΠΆΠ°Ρ‰ΠΈΠ΅ Π² основС TMP, появились Π² C++ вмСстС с шаблонами. НуТно Π±Ρ‹Π»ΠΎ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΊΡ‚ΠΎ-Ρ‚ΠΎ Π·Π°ΠΌΠ΅Ρ‚ΠΈΠ», ΠΊΠ°ΠΊ ΠΎΠ½ΠΈ ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Π½Ρ‹ ΠΈΠ·ΠΎΠ±Ρ€Π΅Ρ‚Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌ ΠΈ Π½Π΅ΠΎΠΆΠΈΠ΄Π°Π½Π½Ρ‹ΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ.

ВСхнология TMP Π΄Π°Π΅Ρ‚ Π΄Π²Π° прСимущСства. Π’ΠΎ-ΠΏΠ΅Ρ€Π²Ρ‹Ρ…, ΠΎΠ½Π° позволяСт Π΄Π΅Π»Π°Ρ‚ΡŒ Ρ‚Π°ΠΊΠΈΠ΅ Π²Π΅Ρ‰ΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΈΠ½Ρ‹ΠΌΠΈ способами ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ Π±Ρ‹Π»ΠΎ Π±Ρ‹ Ρ‚Ρ€ΡƒΠ΄Π½ΠΎ Π»ΠΈΠ±ΠΎ Π²ΠΎΠΎΠ±Ρ‰Π΅ Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ. Π’ΠΎ-Π²Ρ‚ΠΎΡ€Ρ‹Ρ…, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΡˆΠ°Π±Π»ΠΎΠ½Π½Ρ‹Π΅ ΠΌΠ΅Ρ‚Π°ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ ΠΈΡΠΏΠΎΠ»Π½ΡΡŽΡ‚ΡΡ Π²ΠΎ врСмя компиляции C++, ΠΎΠ½ΠΈ ΠΌΠΎΠ³ΡƒΡ‚ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅ΡΡ‚ΠΈΡ‚ΡŒ Ρ‡Π°ΡΡ‚ΡŒ Ρ€Π°Π±ΠΎΡ‚Ρ‹ со стадии исполнСния Π½Π° ΡΡ‚Π°Π΄ΠΈΡŽ компиляции. Π’ частности, Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ошибки, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ Π²ΡΠΏΠ»Ρ‹Π²Π°ΡŽΡ‚ Π²ΠΎ врСмя исполнСния, ΠΌΠΎΠΆΠ½ΠΎ Π±Ρ‹Π»ΠΎ Π±Ρ‹ ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠΈΡ‚ΡŒ ΠΏΡ€ΠΈ компиляции. Π”Ρ€ΡƒΠ³ΠΎΠ΅ прСимущСство – это Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ C++, написанныС с использованиСм TMP, ΠΌΠΎΠΆΠ½ΠΎ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ эффСктивными ΠΏΠΎΡ‡Ρ‚ΠΈ Π²ΠΎ всСх смыслах: ΠΊΠΎΠΌΠΏΠ°ΠΊΡ‚Π½ΠΎΡΡ‚ΡŒ исполняСмого, ΠΊΠΎΠ΄ быстродСйствия, потрСблСния памяти. Но коль скоро Ρ‡Π°ΡΡ‚ΡŒ Ρ€Π°Π±ΠΎΡ‚Ρ‹ пСрСносится Π½Π° ΡΡ‚Π°Π΄ΠΈΡŽ компиляции, Ρ‚ΠΎ, ΠΎΡ‡Π΅Π²ΠΈΠ΄Π½ΠΎ, компиляция Π·Π°ΠΉΠΌΠ΅Ρ‚ большС Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ. Для компиляции ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌ, Π² ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… примСняСтся тСхнология TMP, ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΎΠ²Π°Ρ‚ΡŒΡΡ Π½Π°ΠΌΠ½ΠΎΠ³ΠΎ большС Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ, Ρ‡Π΅ΠΌ для компиляции Π°Π½Π°Π»ΠΎΠ³ΠΈΡ‡Π½Ρ‹Ρ… ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌ, написанных Π±Π΅Π· примСнСния TMP.

Рассмотрим псСвдокод шаблонной Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ advance, прСдставлСнный Π½Π° стр. 227 (см. ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ 47; Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, ΠΈΠΌΠ΅Π΅Ρ‚ смысл ΠΏΠ΅Ρ€Π΅Ρ‡ΠΈΡ‚Π°Ρ‚ΡŒ это ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ сСйчас, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ Π½ΠΈΠΆΠ΅ я ΠΏΡ€Π΅Π΄ΠΏΠΎΠ»Π°Π³Π°ΡŽ, Ρ‡Ρ‚ΠΎ Π²Ρ‹ Π·Π½Π°ΠΊΠΎΠΌΡ‹ с ΠΈΠ·Π»ΠΎΠΆΠ΅Π½Π½Ρ‹ΠΌ Π² Π½Π΅ΠΌ ΠΌΠ°Ρ‚Π΅Ρ€ΠΈΠ°Π»ΠΎΠΌ). Π― Π²Ρ‹Π΄Π΅Π»ΠΈΠ» Π² этом Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚Π΅ Ρ‡Π°ΡΡ‚ΡŒ, Π½Π°ΠΏΠΈΡΠ°Π½Π½ΡƒΡŽ Π½Π° псСвдокодС:


template<typename IterT, typename DistT>

void advance(IterT& iter, DistT d)

{

if (iter являСтся ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€ΠΎΠΌ с ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ»ΡŒΠ½Ρ‹ΠΌ доступом) {

iter += d; // ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€Π½ΡƒΡŽ Π°Ρ€ΠΈΡ„ΠΌΠ΅Ρ‚ΠΈΠΊΡƒ

} // для ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€ΠΎΠ² с ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ»ΡŒΠ½Ρ‹ΠΌ доступом

else {

if(d>=0) {while (d–) ++iter;} // Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ ++ ΠΈΠ»ΠΈ – Π² Ρ†ΠΈΠΊΠ»Π΅

else {while(d++) –iter;} // для ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€ΠΎΠ² Π΄Ρ€ΡƒΠ³ΠΈΡ… ΠΊΠ°Ρ‚Π΅Π³ΠΎΡ€ΠΈΠΉ

}

}


ΠœΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ typeid, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π·Π°ΠΌΠ΅Π½ΠΈΡ‚ΡŒ псСвдокод Ρ€Π΅Π°Π»ΡŒΠ½Ρ‹ΠΌ ΠΊΠΎΠ΄ΠΎΠΌ. Π’ΠΎΠ³Π΄Π° Π·Π°Π΄Π°Ρ‡Π° Π±ΡƒΠ΄Π΅Ρ‚ Ρ€Π΅ΡˆΠ΅Π½Π° Β«Π½ΠΎΡ€ΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΌΒ» для C++ способом – вся Ρ€Π°Π±ΠΎΡ‚Π° выполняСтся Π²ΠΎ врСмя исполнСния:


template<typename IterT, typename DistT>

void advance(IterT& iter, DistT d)

{

if (typeid(typename std::iterator_traits<IterT>::iterator_category)==

typeid(std::random_access_iterator_tag))

iter += d; // ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΈΠ²Π½ΡƒΡŽ Π°Ρ€ΠΈΡ„ΠΌΠ΅Ρ‚ΠΈΠΊΡƒ

} // для ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€ΠΎΠ² с ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ»ΡŒΠ½Ρ‹ΠΌ доступом

else {

if(d>=0) {while (d–) ++iter;} // Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ ++ ΠΈΠ»ΠΈ – Π² Ρ†ΠΈΠΊΠ»Π΅

else {while(d++) –iter;} // для ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€ΠΎΠ² Π΄Ρ€ΡƒΠ³ΠΈΡ… ΠΊΠ°Ρ‚Π΅Π³ΠΎΡ€ΠΈΠΉ

}

}


Π’ ΠΏΡ€Π°Π²ΠΈΠ»Π΅ 47 ΠΎΡ‚ΠΌΠ΅Ρ‡Π΅Π½ΠΎ, Ρ‡Ρ‚ΠΎ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄, основанный Π½Π° typeid, ΠΌΠ΅Π½Π΅Π΅ эффСктивСн, Ρ‡Π΅ΠΌ ΠΏΡ€ΠΈ использовании классов-характСристик, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ Π² этом случаС: (1) ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° Ρ‚ΠΈΠΏΠ° происходит Π²ΠΎ врСмя исполнСния, Π° Π½Π΅ Π²ΠΎ врСмя компиляции, ΠΈ (2) ΠΊΠΎΠ΄, Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡŽΡ‰ΠΈΠΉ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΡƒ Ρ‚ΠΈΠΏΠ°, Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ Π²ΠΊΠ»ΡŽΡ‡Π΅Π½ Π² ΠΈΡΠΏΠΎΠ»Π½ΡΠ΅ΠΌΡƒΡŽ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ. ЀактичСски этот ΠΏΡ€ΠΈΠΌΠ΅Ρ€ ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚, ΠΊΠ°ΠΊ тСхнология TMP ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΠΎΡ€ΠΎΠΆΠ΄Π°Ρ‚ΡŒ Π±ΠΎΠ»Π΅Π΅ эффСктивныС ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ Π½Π° C++, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ характСристики – это ΠΈ Π΅ΡΡ‚ΡŒ частный случай TMP. Напомню, Ρ‡Ρ‚ΠΎ характСристики Π΄Π΅Π»Π°ΡŽΡ‚ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹ΠΌ вычислСниС выраТСния if…else Π²ΠΎ врСмя компиляции.

Π― ΡƒΠΆΠ΅ ΠΎΡ‚ΠΌΠ΅Ρ‡Π°Π» Π²Ρ‹ΡˆΠ΅, Ρ‡Ρ‚ΠΎ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π²Π΅Ρ‰ΠΈ тСхнология TMP позволяСт ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ ΠΏΡ€ΠΎΡ‰Π΅, Ρ‡Π΅ΠΌ Β«Π½ΠΎΡ€ΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΉΒ» C++, ΠΈ advance ΠΌΠΎΠΆΠ½ΠΎ ΡΡ‡ΠΈΡ‚Π°Ρ‚ΡŒ ΠΈΠ»Π»ΡŽΡΡ‚Ρ€Π°Ρ†ΠΈΠΉ этого утвСрТдСния. Π’ ΠΏΡ€Π°Π²ΠΈΠ»Π΅ 47 упоминаСтся ΠΎ Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ основанная Π½Π° typeid рСализация advance ΠΌΠΎΠΆΠ΅Ρ‚ привСсти ΠΊ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ°ΠΌ Π²ΠΎ врСмя компиляции, ΠΈ Π²ΠΎΡ‚ Π²Π°ΠΌ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Ρ‚Π°ΠΊΠΎΠΉ ситуации:


std::list<int>::iterator iter;

...

advance(iter, 10); // ΡΠ΄Π²ΠΈΠ½ΡƒΡ‚ΡŒ iter Π½Π° 10 элСмСнтов Π²ΠΏΠ΅Ρ€Π΅Π΄

// Π½Π΅ скомпилируСтся для ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π½ΠΎΠΉ

// Π²Ρ‹ΡˆΠ΅ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ


Рассмотрим Π²Π΅Ρ€ΡΠΈΡŽ advance, которая Π±ΡƒΠ΄Π΅Ρ‚ сгСнСрирована для этого Π²Ρ‹Π·ΠΎΠ²Π°. ПослС подстановки Ρ‚ΠΈΠΏΠΎΠ² iter ΠΈ 10 Π² качСствС ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² шаблона IterT ΠΈ DistT ΠΌΡ‹ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠΌ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π΅:


void advance(std::list<int>::iterator& iter, int d)

{

if (typeid(std::iterator_traits<std::list<int>::iterator>::iterator_category)==

typeid(std::random_access_iterator_tag))

iter += d; // ошибка!

}

else {

if(d>=0) {while (d–) ++iter;}

else {while(d++) –iter;}

}

}


ΠŸΡ€ΠΎΠ±Π»Π΅ΠΌΠ° Π² Π²Ρ‹Π΄Π΅Π»Π΅Π½Π½ΠΎΠΉ строкС, Π³Π΄Π΅ встрСчаСтся ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ +=. Π’ Π΄Π°Π½Π½ΠΎΠΌ случаС ΠΌΡ‹ пытаСмся ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ += для Ρ‚ΠΈΠΏΠ° list<int>::iterator, Π½ΠΎ list<int>::iterator – это Π΄Π²ΡƒΠ½Π°ΠΏΡ€Π°Π²Π»Π΅Π½Π½Ρ‹ΠΉ ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€ (см. ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ 47), поэтому ΠΎΠ½ Π½Π΅ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ +=. ΠžΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ += ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°ΡŽΡ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€Ρ‹ с ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ»ΡŒΠ½Ρ‹ΠΌ доступом. ΠœΡ‹ Π·Π½Π°Π΅ΠΌ, Ρ‡Ρ‚ΠΎ Π½ΠΈΠΊΠΎΠ³Π΄Π° Π½Π΅ попытаСмся ΠΈΡΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ ΠΏΡ€Π΅Π΄Π»ΠΎΠΆΠ΅Π½ΠΈΠ΅, содСрТащСС +=, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ для list<int>::iterator ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° с ΠΏΡ€ΠΈΠ²Π»Π΅Ρ‡Π΅Π½ΠΈΠ΅ΠΌ typeid Π½ΠΈΠΊΠΎΠ³Π΄Π° Π½Π΅ выполнится ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ, Π½ΠΎ компилятор-Ρ‚ΠΎ обязан Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ вСсь исходный ΠΊΠΎΠ΄ ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π΅Π½, Π΄Π°ΠΆΠ΅ Ссли ΠΎΠ½ Π½ΠΈΠΊΠΎΠ³Π΄Π° Π½Π΅ исполняСтся, Π° Β«iter += dΒ» – Π½Π΅ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½Ρ‹ΠΉ ΠΊΠΎΠ΄ Π² случаС, ΠΊΠΎΠ³Π΄Π° iter Π½Π΅ являСтся ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€ΠΎΠΌ с ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ»ΡŒΠ½Ρ‹ΠΌ доступом. РСшСниС ΠΆΠ΅ Π½Π° основС Ρ‚Π΅Ρ…Π½ΠΎΠ»ΠΎΠ³ΠΈΠΈ TMP ΠΏΡ€Π΅Π΄ΠΏΠΎΠ»Π°Π³Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ ΠΊΠΎΠ΄ для Ρ€Π°Π·Π½Ρ‹Ρ… Ρ‚ΠΈΠΏΠΎΠ² вынСсСн Π² Ρ€Π°Π·Π½Ρ‹Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, каТдая ΠΈΠ· ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ, ΠΏΡ€ΠΈΠΌΠ΅Π½ΠΈΠΌΡ‹Π΅ ΠΊ Ρ‚ΠΈΠΏΠ°ΠΌ, для ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… ΠΎΠ½Π° написана.

Π‘Ρ‹Π»ΠΎ Π΄ΠΎΠΊΠ°Π·Π°Π½ΠΎ, Ρ‡Ρ‚ΠΎ тСхнология TMP прСдставляСт собой ΠΏΠΎΠ»Π½ΡƒΡŽ ΠΌΠ°ΡˆΠΈΠ½Ρƒ Π’ΡŒΡŽΡ€ΠΈΠ½Π³Π°, Ρ‚ΠΎ Π΅ΡΡ‚ΡŒ ΠΎΠ±Π»Π°Π΄Π°Π΅Ρ‚ достаточной ΠΌΠΎΡ‰ΡŒΡŽ для Π»ΡŽΠ±Ρ‹Ρ… вычислСний. Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ TMP, Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΎΠ±ΡŠΡΠ²Π»ΡΡ‚ΡŒ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅, Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒ Ρ†ΠΈΠΊΠ»Ρ‹, ΠΏΠΈΡΠ°Ρ‚ΡŒ ΠΈ Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΈ Ρ‚. Π΄. Но Ρ‚Π°ΠΊΠΈΠ΅ конструкции выглядят ΡΠΎΠ²Π΅Ρ€ΡˆΠ΅Π½Π½ΠΎ ΠΈΠ½Π°Ρ‡Π΅, Ρ‡Π΅ΠΌ ΠΈΡ… Π°Π½Π°Π»ΠΎΠ³ΠΈ ΠΈΠ· Β«Π½ΠΎΡ€ΠΌΠ°Π»ΡŒΠ½ΠΎΠ³ΠΎΒ» C++. НапримСр, Π² ΠΏΡ€Π°Π²ΠΈΠ»Π΅ 47 ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ, ΠΊΠ°ΠΊ Π² TMP условныС прСдлоТСния if…else Π²Ρ‹Ρ€Π°ΠΆΠ°ΡŽΡ‚ΡΡ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ шаблонов ΠΈ ΠΈΡ… спСциализаций. Но Ρ‚Π°ΠΊΠΈΠ΅ конструкции ΠΌΠΎΠΆΠ½ΠΎ Π½Π°Π·Π²Π°Ρ‚ΡŒ Β«TMP уровня ассСмблСра». Π’ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ°Ρ… для Ρ€Π°Π±ΠΎΡ‚Ρ‹ с TMP (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, MPL ΠΈΠ· Boost – см. ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ 55) прСдлагаСтся Π±ΠΎΠ»Π΅Π΅ высокоуровнСвый синтаксис, хотя Π΅Π³ΠΎ Ρ‚Π°ΠΊΠΆΠ΅ нСльзя ΠΏΡ€ΠΈΠ½ΡΡ‚ΡŒ Π·Π° Β«Π½ΠΎΡ€ΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΉΒ» Π‘++.

Π§Ρ‚ΠΎΠ±Ρ‹ Π²Π·Π³Π»ΡΠ½ΡƒΡ‚ΡŒ Π½Π° TMP с Π΄Ρ€ΡƒΠ³ΠΎΠ³ΠΎ Π±ΠΎΠΊΡƒ, посмотрим, ΠΊΠ°ΠΊ Ρ‚Π°ΠΌ выглядят Ρ†ΠΈΠΊΠ»Ρ‹. ВСхнология TMP Π½Π΅ прСдоставляСт настоящих цикличСских конструкций, поэтому Ρ†ΠΈΠΊΠ» модСлируСтся с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ рСкурсии. (Если Π²Ρ‹ Π½Π΅ ΠΎΡ‡Π΅Π½ΡŒ ΡƒΠ²Π΅Ρ€Π΅Π½Π½ΠΎ Π²Π»Π°Π΄Π΅Π΅Ρ‚Π΅ рСкурсиСй, придСтся ΠΎΡΠ²ΠΎΠΈΡ‚ΡŒΡΡ с Π½Π΅ΠΉ ΠΏΡ€Π΅ΠΆΠ΄Π΅, Ρ‡Π΅ΠΌ ΠΏΡ€ΠΈΡΡ‚ΡƒΠΏΠ°Ρ‚ΡŒ ΠΊ использованию TMP. Π’Π΅Π΄ΡŒ TMP – ΠΏΠΎ сущСству Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½Ρ‹ΠΉ язык, Π° для Ρ‚Π°ΠΊΠΈΡ… языков рСкурсия – Ρ‚ΠΎ ΠΆΠ΅, Ρ‡Ρ‚ΠΎ Ρ‚Π΅Π»Π΅Π²ΠΈΠ΄Π΅Π½ΠΈΠ΅ для амСриканской ΠΏΠΎΠΏ-ΠΊΡƒΠ»ΡŒΡ‚ΡƒΡ€Ρ‹ – Π½Π΅ΠΎΡ‚ΡŠΠ΅ΠΌΠ»Π΅ΠΌΠ°Ρ ΠΏΡ€ΠΈΠ½Π°Π΄Π»Π΅ΠΆΠ½ΠΎΡΡ‚ΡŒ.) Но ΠΈ рСкурсия-Ρ‚ΠΎ Π½Π΅ совсСм обычная, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΏΡ€ΠΈ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ Ρ†ΠΈΠΊΠ»ΠΎΠ² TMP Π½Π΅Ρ‚ рСкурсивных Π²Ρ‹Π·ΠΎΠ²ΠΎΠ² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ, Π° Π΅ΡΡ‚ΡŒ рСкурсивныС ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚ΠΈΠ·Π°Ρ†ΠΈΠΈ шаблонов.

Аналогом ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ Β«Hello WorldΒ» Π½Π° TMP являСтся вычислСниС Ρ„Π°ΠΊΡ‚ΠΎΡ€ΠΈΠ°Π»Π° Π²ΠΎ врСмя компиляции. ΠšΠΎΠ½Π΅Ρ‡Π½ΠΎ, ΠΎΠ½Π°, ΠΊΠ°ΠΊ ΠΈ Β«Hello WorldΒ», Π½Π΅ ΠΏΠΎΡ€Π°Π·ΠΈΡ‚ Π²ΠΎΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅, Π½ΠΎ ΠΎΠ±Π΅ ΠΏΠΎΠ»Π΅Π·Π½Ρ‹ для дСмонстрации Π±Π°Π·ΠΎΠ²Ρ‹Ρ… возмоТностСй языка. ВычислСниС Ρ„Π°ΠΊΡ‚ΠΎΡ€ΠΈΠ°Π»Π° с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ TMP сводится ΠΊ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ рСкурсивных ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚ΠΈΠ·Π°Ρ†ΠΈΠΉ шаблона. ΠšΡ€ΠΎΠΌΠ΅ Ρ‚ΠΎΠ³ΠΎ, дСмонстрируСтся ΠΎΠ΄ΠΈΠ½ ΠΈΠ· способов создания ΠΈ использования ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… Π² TMP. Π‘ΠΌΠΎΡ‚Ρ€ΠΈΡ‚Π΅:


template<unsigned n> // ΠΎΠ±Ρ‰ΠΈΠΉ случай: Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Factorial<n> β€“ это

struct Factorial { // ΠΏΡ€ΠΎΠΈΠ·Π²Π΅Π΄Π΅Π½ΠΈΠ΅ n ΠΈ Factorial<n-1>

enum { value = n*Factorial<n-1>::value };

};

template<> // частный случай: Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Factorial<0> β€“

struct Factorial<0> { // это 1

enum { value = 1 };

};


ИмСя Ρ‚Π°ΠΊΡƒΡŽ ΡˆΠ°Π±Π»ΠΎΠ½Π½ΡƒΡŽ ΠΌΠ΅Ρ‚Π°ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ (Π½Π° самом Π΄Π΅Π»Π΅ просто Π΅Π΄ΠΈΠ½ΡΡ‚Π²Π΅Π½Π½ΡƒΡŽ ΡˆΠ°Π±Π»ΠΎΠ½Π½ΡƒΡŽ ΠΌΠ΅Ρ‚Π°Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ Factorial), Π²Ρ‹ ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚Π΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Ρ„Π°ΠΊΡ‚ΠΎΡ€ΠΈΠ°Π»Π° n, ΠΎΠ±Ρ€Π°Ρ‰Π°ΡΡΡŒ ΠΊ Factorial<n>::value.

ЦикличСская Ρ‡Π°ΡΡ‚ΡŒ ΠΊΠΎΠ΄Π° Π²ΠΎΠ·Π½ΠΈΠΊΠ°Π΅Ρ‚ Ρ‚Π°ΠΌ, Π³Π΄Π΅ конкрСтизация шаблона Factorial<n> ссылаСтся Π½Π° ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚ΠΈΠ·Π°Ρ†ΠΈΡŽ шаблона Factorial<n-1>. Как Π²ΠΎ всякой рСкурсивной ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅, здСсь Π΅ΡΡ‚ΡŒ особый случай, ΠΏΡ€Π΅ΠΊΡ€Π°Ρ‰Π°ΡŽΡ‰ΠΈΠΉ Ρ€Π΅ΠΊΡƒΡ€ΡΠΈΡŽ. Π’ Π΄Π°Π½Π½ΠΎΠΌ случаС это спСциализация шаблона Factorial<0>.