Introducere în magia șabloanelor, savepearlharbor

Șabloanele în C ++ sunt instrumente de metaprogramare și implementează polimorfismul de compilare. Ce este?
Acesta este momentul în care scriem coduri cu comportament polimorf, dar comportamentul în sine este determinat la etapa de compilare - adică. în contrast cu polimorfismul funcțiilor virtuale, codul binar rezultat va avea deja un comportament constant.


Folosim modele pentru frumusete. Fiecare dezvoltator C ++ știe ce frumusețe este, frumusețea este atunci când codul este compact. ușor de înțeles și rapid.

Meta-magie și interfețe implicite

Primele vrăji: clubul magic


Să concretizăm șablonul nostru și să vedem ce tipuri avem pentru parametrii de șablon diferiți:

Rezultatul programului arată că tipurile de instanțieri ale șablonului sunt diferite chiar și pentru tipurile echivalente - caracterele nesemnate # 038; char. Ele sunt identice pentru char # 038; CHAR, t. typedef nu creează un tip, ci doar îi dă un nume diferit. Ele sunt aceleași pentru expresiile 1 și 2-1, deoarece compilatorul evaluează expresiile și utilizează 1 în loc de 2-1.
Prin urmare, rezultă că nu putem folosi o compilație separată pentru șabloane fără probleme suplimentare:

În general, în standardul C ++, există un cuvânt cheie de export pentru acest lucru. Cu toate acestea, această caracteristică este prea greu de implementat și lipsește în majoritatea compilatoarelor. Există compilatoare care îl suportă, dar nu recomand să fie folosit în codul portabil.
În plus față de clase există și șabloane de funcții:

Dacă compilatorul poate afișa tipul parametrului șablon din tipul parametrului, acesta va face acest lucru, dar nu este necesar să îl specificăm în cod. Dacă nu, atunci putem defini funcția de rezolvare:

Nu suportă nicio cheltuială.

Specializarea este un nou nivel


De obicei, folosind șabloane, vrem să scriem un cod universal, dar în unele cazuri putem pierde performanța. Pentru a rezolva problema, există o vrajă specială - specializarea chalonului. Specializarea este re-definirea unui șablon cu un anumit tip sau clasă de tipuri.

Compilatorul va alege cea mai precisă specializare potrivită, în exemplul căruia este un tip de tip "pointer to type".

Sinistru Magic: Recursiune

Specializările și faptul că putem folosi șabloanele în șabloane oferă femeilor o posibilitate foarte interesantă - recursul timpului de compilare.

Cel mai simplu și mai popular exemplu este calculul unei serii sau al unui polinom, adică suma unei progresii aritmetice:

Arătăm ... Lucrări! Se răcește? Să creștem numărul de iterații la 500:

Acum, compilarea durează mai mult timp, timpul de execuție al programului este constant! Miracole!

Nu țipa dacă vrei o furtună

Sunt câteva momente.

Adâncimea maximă a recursivității este limitată în mod implicit, pentru noua gcc este de 900, pentru versiunile mai vechi este mai mică. parametru

elimină această restricție.
A doua capcană - nu așteptați rapoartele de eroare. Schimbăm progresia la factoriali:

Avem un rezultat incorect și nu un singur avertisment ...
Al treilea punct, evident: putem crea prea multe instanŃieri aproape identice ale șablonului și în locul câștigului de performanŃă se obține incrementarea codului binar.

Vrăjile puternice ale antici

Este posibilă combinarea magiei de moștenire cu magia șablonului?

Anticii folosesc vraja CRTP pentru a face acest lucru. Ideea este simplă: nu aplicați moștenirea virtuală și asigurați comportamentul polimorf prin convertirea explicită a unui tip de moștenitor la un tip parental. Să ne uităm la un exemplu de utilizare.

Obținem metode inline cu comportamente polimorfe! Cine va spune că acest lucru nu este rece - dușmanul meu pentru totdeauna.
Anticii sunt, de asemenea, sfătuiți să adăugați ceva de genul acesta constructorului părintelui:

astfel încât demonii, treziți de o vrajă puternică, nu puteau face rău magicianului care ia chemat.

Există încă multe tehnici secrete, vechi și nu foarte mult. Sper pentru o întâlnire rapidă / * în iad * /, și poate puterea antichităților să vină cu tine.

Articole similare