You are on page 1of 13

IDZ DO

PRZYKADOWY ROZDZIA
SPIS TRECI

KATALOG KSIEK
KATALOG ONLINE
ZAMW DRUKOWANY KATALOG

TWJ KOSZYK

Jzyk C++.
Metaprogramowanie
za pomoc szablonw
Autorzy: David Abrahams, Aleksey Gurtovoy
Tumaczenie: Rafa Joca
ISBN: 83-7361-935-6
Tytu oryginau: C++ Template Metaprogramming:
Concepts, Tools, and Techniques from Boost and Beyond
Format: B5, stron: 336

DODAJ DO KOSZYKA

CENNIK I INFORMACJE
ZAMW INFORMACJE
O NOWOCIACH
ZAMW CENNIK

CZYTELNIA
FRAGMENTY KSIEK ONLINE

Metaprogramowanie to jedna z nowoci, ktre pojawiy si ostatnio w wiecie jzyka


C++. Metaprogram to program bdcy w stanie modyfikowa lub generowa kod
innego programu. Wykorzystanie zasad metaprogramowania pozwala na przykad
na dynamiczn modyfikacj programu podczas jego kompilacji. Pierwszym jzykiem
pozwalajcym na korzystanie z moliwoci metaprogramowania jest C++ bibliotek STL.
C++. Metaprogramowanie za pomoc szablonw to ksika przeznaczona dla tych
programistw, ktrzy korzystaj ju z biblioteki STL i chc zastosowa j do tworzenia
metaprogramw. Opisano w niej zasady metaprogramowania, typy moliwe do
wykorzystania w szablonach przeznaczonych do implementacji funkcji zwizanych
z metaprogramowaniem oraz sposoby tworzenia szablonw modyfikujcych programy
podczas kompilacji.
Typy i metafunkcje
Operacje, sekwencje i iteratory
Algorytmy biblioteki MPL i tworzenie wasnych algorytmw
Usuwanie bdw w szablonach
Modyfikowanie programu w czasie kompilacji
Jzyk DSEL
Metaprogramowanie to nowo. Poznaj je ju teraz, aby by przygotowanym na dzie,
w ktrym stanie si standardem.

Wydawnictwo Helion
ul. Chopina 6
44-100 Gliwice
tel. (32)230-98-63
e-mail: helion@helion.pl

Spis treci
Przedmowa ....................................................................................... 7
Podzikowania .................................................................................. 9
Struktura ksiki ............................................................................ 11
Rozdzia 1. Wprowadzenie ................................................................................ 13
1.1. Zaczynamy ............................................................................................................. 13
1.2. Czym jest metaprogram? ....................................................................................... 14
1.3. Metaprogramowanie w jzyku macierzystym ........................................................ 15
1.4. Metaprogramowanie w jzyku C++ ....................................................................... 15
1.5. Dlaczego metaprogramowanie? ............................................................................. 18
1.6. Kiedy stosowa metaprogramowanie? ................................................................... 20
1.7. Dlaczego biblioteka metaprogramowania? ............................................................ 20

Rozdzia 2. Cechy typu i manipulowanie nim ...................................................... 23


2.1. Powizanie typw .................................................................................................. 23
2.2. Metafunkcje ........................................................................................................... 26
2.3. Metafunkcje numeryczne ....................................................................................... 29
2.4. Dokonywanie wyborw na etapie kompilacji ........................................................ 30
2.5. Krtka podr po bibliotece Boost Type Traits ..................................................... 34
2.6. Metafunkcje bezargumentowe ............................................................................... 39
2.7. Definicja metafunkcji ............................................................................................ 40
2.8. Historia .................................................................................................................. 40
2.9. Szczegy ............................................................................................................... 41
2.10. wiczenia .............................................................................................................. 44

Rozdzia 3. Dokadniejsze omwienie metafunkcji .............................................. 47


3.1. Analiza wymiarowa ............................................................................................... 47
3.2. Metafunkcje wyszych rzdw .............................................................................. 56
3.3. Obsuga symboli zastpczych ................................................................................ 58
3.4. Wicej moliwoci lambdy .................................................................................... 60
3.5. Szczegy implementacji lambda ........................................................................... 61
3.6. Szczegy ............................................................................................................... 64
3.7. wiczenia .............................................................................................................. 66

Rozdzia 4. Operacje i otoczki typw cakowitych .............................................. 69


4.1. Operacje i otoczki typu logicznego ........................................................................ 69
4.2. Operacje i otoczki liczb cakowitych ..................................................................... 76
4.3. wiczenia .............................................................................................................. 80

Spis treci

Rozdzia 5. Sekwencje i iteratory ...................................................................... 83


5.1. Pojcia ................................................................................................................... 83
5.2. Sekwencje i algorytmy ........................................................................................... 84
5.3. Iteratory ................................................................................................................. 85
5.4. Pojcia zwizane z iteratorem ................................................................................ 85
5.5. Pojcia sekwencji ................................................................................................... 89
5.6. Rwno sekwencji ............................................................................................... 94
5.7. Wewntrzne operacje sekwencji ............................................................................ 94
5.8. Klasy sekwencji ..................................................................................................... 95
5.9. Otoczki sekwencji liczb cakowitych ..................................................................... 99
5.10. Wyprowadzanie sekwencji .................................................................................. 100
5.11. Pisanie wasnych sekwencji ................................................................................. 101
5.12. Szczegy ............................................................................................................ 110
5.13. wiczenia ............................................................................................................ 111

Rozdzia 6. Algorytmy ..................................................................................... 115


6.1. Algorytmy, idiomy, wielokrotne uycie i abstrakcja ........................................... 115
6.2. Algorytmy biblioteki MPL .................................................................................. 117
6.3. Insertery ............................................................................................................... 118
6.4. Podstawowe algorytmy sekwencji ....................................................................... 121
6.5. Algorytmy zapyta .............................................................................................. 123
6.6. Algorytmy budowania sekwencji ......................................................................... 123
6.7. Pisanie wasnych algorytmw .............................................................................. 126
6.8. Szczegy ............................................................................................................. 127
6.9. wiczenia ............................................................................................................ 128

Rozdzia 7. Widoki i adaptery iteratorw ......................................................... 131


7.1. Kilka przykadw ................................................................................................. 131
7.2. Pojcie widoku .................................................................................................... 137
7.3. Adaptery iteratora ................................................................................................ 137
7.4. Tworzenie wasnego widoku ............................................................................... 138
7.5. Historia ................................................................................................................ 140
7.6. wiczenia ............................................................................................................ 140

Rozdzia 8. Diagnostyka ................................................................................. 143


8.1. Powie o poprawianiu bdw ........................................................................... 143
8.2. Korzystanie z narzdzi do analizy wynikw diagnostyki .................................... 152
8.3. Zamierzone generowanie komunikatw diagnostycznych ................................... 156
8.4. Historia ................................................................................................................ 167
8.5. Szczegy ............................................................................................................. 167
8.6. wiczenia ............................................................................................................ 168

Rozdzia 9. Przekraczanie granicy midzy czasem kompilacji


i wykonywania programu ............................................................... 171
9.1. Algorytm for_each ............................................................................................... 171
9.2. Wybr implementacji .......................................................................................... 174
9.3. Generatory obiektw ............................................................................................ 178
9.4. Wybr struktury ................................................................................................... 180
9.5. Zoenie klas ........................................................................................................ 184
9.6. Wskaniki na funkcje (skadowe) jako argumenty szablonw ............................ 187
9.7. Wymazywanie typu ............................................................................................. 189
9.8. Wzorzec zadziwiajco powracajcego szablonu .................................................. 195
9.9. Jawne zarzdzanie zbiorem przecie ................................................................ 200
9.10. Sztuczka z sizeof ................................................................................................. 202
9.11. Podsumowanie ..................................................................................................... 203
9.12. wiczenia ............................................................................................................ 203

Spis treci

Rozdzia 10. Jzyk osadzony zaleny od dziedziny .............................................. 205


10.1. May jzyk ....................................................................................................... 205
10.2. przechodzi dug drog .................................................................................... 208
10.3. Jzyki DSL podejcie odwrotne ..................................................................... 215
10.4. C++ jako jzyk gospodarza ................................................................................. 218
10.5. Blitz++ i szablony wyrae ................................................................................. 220
10.6. Jzyki DSEL oglnego stosowania ...................................................................... 225
10.7. Biblioteka Boost Spirit ........................................................................................ 234
10.8. Podsumowanie ..................................................................................................... 240
10.9. wiczenia ............................................................................................................ 241

Rozdzia 11. Przykad projektowania jzyka DSEL .............................................. 243


11.1. Automaty skoczone ........................................................................................... 243
11.2. Cele projektu szkieletu ........................................................................................ 246
11.3. Podstawy interfejsu szkieletu .............................................................................. 247
11.4. Wybr jzyka DSL .............................................................................................. 248
11.5. Implementacja ..................................................................................................... 254
11.6. Analiza ................................................................................................................ 259
11.7. Kierunek rozwoju jzyka ..................................................................................... 261
11.8. wiczenia ............................................................................................................ 261

Dodatek A Wprowadzenie do metaprogramowania za pomoc preprocesora ..... 265


A.1. Motywacja ........................................................................................................... 265
A.2. Podstawowe abstrakcje preprocesora ................................................................... 267
A.3. Struktura biblioteki preprocesora ......................................................................... 269
A.4. Abstrakcje biblioteki preprocesora ....................................................................... 269
A.5. wiczenie ............................................................................................................. 286

Dodatek B Sowa kluczowe typename i template ............................................ 287


B.1. Zagadnienia .......................................................................................................... 288
B.2. Reguy .................................................................................................................. 291

Dodatek C Wydajno kompilacji ................................................................... 299


C.1. Model obliczeniowy ............................................................................................. 299
C.2. Zarzdzanie czasem kompilacji ............................................................................ 302
C.3. Testy ..................................................................................................................... 302

Dodatek D Podsumowanie przenonoci biblioteki MPL ................................. 315


Bibliografia ................................................................................... 317
Skorowidz ..................................................................................... 321

Rozdzia 1.

Wprowadzenie
Warto potraktowa ten rozdzia jako rozgrzewk przed pozosta czci ksiki.
Przewiczymy tutaj najwaniejsze narzdzia, a take zapoznamy si z podstawowymi
pojciami i terminologi. Pod koniec rozdziau kady powinien ju mniej wicej wiedzie, o czym jest niniejsza ksika, i by godnym kolejnych informacji.

1.1. Zaczynamy
Jedn z przyjemnych kwestii zwizanych z metaprogramowaniem szablonami jest
wspdzielenie pewnej waciwoci z tradycyjnymi, starymi systemami. Po napisaniu
metaprogramu mona go uywa bez zastanawiania si nad jego szczegami
oczywicie o ile wszystko dziaa prawidowo.
Aby uwiadomi kademu, e przedstawiona kwestia to nie tylko wymylna teoria,
prezentujemy prosty program C++, ktry po prostu uywa elementu zaimplementowanego jako metaprogram szablonu.

    

  


 

     !
 !
"

Nawet jeli jest si dobrym w arytmetyce binarnej i od razu mona odgadn wynik
dziaania programu bez jego uruchamiania, warto zada sobie ten trud i go skompilowa oraz uruchomi. Poza upewnieniem si w kwestii samej koncepcji, jest to dobry
test sprawdzajcy, czy wykorzystywany kompilator potrafi obsuy kod przedstawiany w ksice. Wynikiem dziaania programu powinno by wywietlenie na standardowym wyjciu wartoci dziesitnej liczby binarnej 101010:
#$

Rozdzia 1. Wprowadzenie

14

1.2. Czym jest metaprogram?


Gdy potraktowa sowo metaprogram dosownie, oznacza ono program o programie1.
Od strony bardziej praktycznej metaprogram to program modyfikujcy kod. Cho sama
koncepcja brzmi nieco dziwacznie, zapewne nieraz niewiadomie korzystamy z takich
rozwiza. Przykadem moe by kompilator C++, ktry modyfikuje kod C++ w taki
sposb, by uzyska kod w asemblerze lub kod maszynowy.
Generatory analizatorw skadniowych takie jak YACC [Joh79] to kolejny przykad
programw manipulujcych programem. Wejciem dla YACC jest wysokopoziomowy
opis analizatora skadniowego zawierajcy zasady gramatyczne i odpowiednie polecenia umieszczone w nawiasach klamrowych. Aby na przykad przetworzy i wykona dziaania arytmetyczne zgodnie z przyjt kolejnoci wykonywania dziaa,
mona zastosowa nastpujcy opis gramatyki dla programu YACC.
%   
& %  '('   )) * ) ( )+! "
& %  ','   )) * ) , )+! "
!
  -
&  '.' -  )) * ) . )+! "
&  ' ' -  )) * ) )+! "
!
-  /012324
& 5
!
5  '' %  ''
!

Program YACC wygeneruje plik rdowy jzyka C++ zawierajcy (poza wieloma
innymi elementami) funkcj , ktr wywouje si w celu przeanalizowania
tekstu zgodnie z podan gramatyk i wykonania okrelonych dziaa2.
 

%   !
  !
"

Uytkownicy programu YACC dziaaj przede wszystkim w dziedzinie projektowania analizatorw skadniowych, wic jzyk YACC mona nazwa jzykiem specjalistycznym (dziedzinowym). Poniewa pozostaa cz gwnego programu wymaga
zastosowania oglnego jzyka programowania i musi si komunikowa z analizatorem skadniowym, YACC konwertuje jzyk specjalistyczny na jzyk macierzysty, C,
ktry uytkownik kompiluje i konsoliduje z pozostaym kodem. Jzyk specjalistyczny
przechodzi wic przez dwa kroki przeksztace, a uytkownik bardzo dobrze zna granic midzy nim a pozosta czci programu gwnego.
1

W filozofii, podobnie jak w programowaniu, przedrostek meta oznacza o lub o jeden poziom
opisowy wyej. Wynika to z oryginalnego greckiego znaczenia ponad lub poza.
Oczywicie trzeba jeszcze zaimplementowa odpowiedni funkcj % dokonujc rozbioru tekstu.
W rozdziale 10. znajduje si peny przykad. Ewentualnie warto zajrze do dokumentacji programu YACC.

1.4. Metaprogramowanie w jzyku C++

15

1.3. Metaprogramowanie
w jzyku macierzystym
YACC to przykad translatora metaprogramu, ktrego jzyk specjalistyczny rni
si od jzyka macierzystego. Bardziej interesujca posta metaprogramowania jest
dostpna w jzykach takich jak Scheme [SS75]. Programista metaprogramu Scheme
definiuje wasny jzyk specjalistyczny jako podzbir dopuszczalnych programw samego jzyka Scheme. Metaprogram wykonuje si w tym samym kroku przeksztace
co pozostaa cz programu uytkownika. Programici czsto przemieszczaj si
midzy typowym programowaniem, metaprogramowaniem i pisaniem jzykw specjalistycznych, nawet tego nie dostrzegajc. Co wicej, potrafi w sposb niemale
nierozrnialny scali w tym samym systemie wiele dziedzin.
Co ciekawe, kompilator C++ zapewnia niemale dokadnie tak sam uyteczno
metaprogramowania jak przedstawiony wczeniej przykad. Pozostaa cz ksiki
omawia odblokowywanie siy tkwicej w szablonach i opisuje sposoby jej uycia.

1.4. Metaprogramowanie w jzyku C++


W jzyku C++ metaprogramowanie odkryto niemale przypadkowo ([Unruh94],
[Veld95b]), gdy udowodniono, i szablony zapewniaj bardzo elastyczny jzyk
metaprogramowania. W niniejszym podrozdziale omwimy podstawowe mechanizmy
i typowe rozwizania uywane w metaprogramowaniu w jzyku C++.

1.4.1. Obliczenia numeryczne


Najprostsze metaprogramy C++ wykonuj obliczenia na liczbach cakowitych w trakcie
kompilacji. Jeden z pierwszych metaprogramw zosta przedstawiony na spotkaniu
komitetu C++ przez Erwina Unruha w zasadzie by to niedozwolony fragment kodu, ktrego komunikat o bdzie zawiera cig wyliczonych liczb pierwszych!
Poniewa niedozwolonego kodu nie da si wydajnie stosowa w duych systemach,
przyjrzyjmy si bardziej praktycznym aplikacjom. Kolejny metaprogram (ktry ley
u podstaw przedstawionego wczeniej testu kompilatora) zamienia liczby dziesitne bez
znaku na ich odpowiedniki binarne, co umoliwia wyraanie staych binarnych w przyjaznej formie.
  5 5 0
 

  5   
* 0   . $ dodaje bardziej znaczcy bit
( 06! przejcie do mniej znaczcego bitu
"!

Rozdzia 1. Wprowadzenie

16

  specjalizacja
  przerywa rekurencj

  5    * !
"!
 5    * 
 5    * 
 5   -  * 
 5     * 
 5    * 

!
!
!
!
!

Jeeli kto zastanawia si, gdzie jest program, proponujemy rozway, co si stanie
w momencie prby dostpu do zagniedonej skadowej
  z . Tworzy si egzemplarze szablonu  z coraz to mniejszymi  a do osignicia przez
 zera. Warunkiem koca jest specjalizacja. Innymi sowy, przypomina to dziaanie
funkcji rekurencyjnej. Czy jest to program czy moe funkcja? Oglnie rzecz biorc,
kompilator zinterpretuje ten krtki metaprogram.
Sprawdzanie bdw
Nic nie stoi na przeszkodzie, aby uytkownik przekaza do  warto 678,
ktra nie jest poprawn wartoci binarn. Wynik na pewno nie bdzie sensowny
(zostanie wykonane dziaanie 622+721+820), a przekazanie wartoci 678 na pewno
wskazuje bd uytkownika. W rozdziale 3. przedstawimy rozwizanie zapewniajce, i

  skompiluje si tylko wtedy, gdy reprezentacja dziesitna  bdzie
si skadaa tylko z samych zer i jedynek.

Poniewa jzyk C++ wprowadza rozrnienie midzy wyraeniami obliczanymi w trakcie


kompilacji i w trakcie dziaania programu, metaprogramy wygldaj inaczej ni ich
tradycyjne odpowiedniki. Podobnie jak w Scheme programista metaprogramw C++
pisze kod w tym samym jzyku co tradycyjne programy, ale w C++ ma dostp tylko
do podzbioru elementw jzyka zwizanych z etapem kompilacji. Porwnajmy poprzedni program z prost wersj  wykonan jako tradycyjny program.
 5  5 5 0

 0 **  7   06 ( $ . 0 !
"

Podstawowa rnica midzy przedstawionymi wersjami polega na sposobie obsugi


warunku zakoczenia: metaprogram uywa specjalizacji szablonu do opisu tego, co
dzieje si dla  rwnego zero. Przerywanie za pomoc specjalizacji to element wsplny
niemal dla wszystkich metaprogamw C++, cho czasem wszystko ukryte jest za interfejsem biblioteki metaprogramowania.
Inn bardzo wan rnic midzy jzykiem C++ tradycyjnym i wykonywanym w trakcie
kompilacji obrazuje ponisza wersja , ktra korzysta z ptli  zamiast z rekurencji.
 5  5 5 0

 5   * !
-  5  * %! 0! 0 * 8  * 

1.4. Metaprogramowanie w jzyku C++

17


- 06
  (* !
"
  !
"

Cho ta wersja jest dusza od rozwizania rekurencyjnego, zapewne zastosuje j


wikszo programistw C++, gdy jest na og wydajniejsza od rekurencji.
Cz jzyka C++ zwizana z czasem kompilacji nazywana jest czsto jzykiem
czysto funkcyjnym, a to z powodu waciwoci, jakie wspdzieli z jzykami takimi
jak Haskell: (meta)dane s niezmienne, a (meta)funkcje nie mog mie efektw
ubocznych. Wynika z tego, i C++ czasu kompilacji nie posiada tradycyjnych zmiennych uywanych w typowym jzyku C++. Poniewa nie mona napisa ptli (poza
ptl nieskoczon) bez sprawdzania pewnego zmiennego stanu zakoczenia, iteracje
po prostu nie s dostpne w trakcie kompilacji. Z tego wzgldu w metaprogramach
C++ wszechobecna jest rekurencja.

1.4.2. Obliczenia typu


Duo waniejsza od obliczania wartoci liczbowych w trakcie kompilacji jest zdolno jzyka C++ do obliczania typw. W zasadzie w pozostaej czci ksiki dominuje obliczanie typu pierwszy przykad przedstawiamy ju na pocztku kolejnego
rozdziau. Cho jestemy tutaj bardzo bezporedni, zapewne wikszo osb traktuje
metaprogramowanie szablonami jako obliczenia zwizane z typami.
Cho dla dobrego zrozumienia oblicze typw warto przeczyta rozdzia 2., ju teraz
zamierzamy przedstawi przedsmak ich siy. Pamitasz kalkulator wyrae wykonany
w YACC? Wychodzi na to, i nie potrzebujemy translatora, aby osign podobne dziaanie. Po odpowiednim otoczeniu kodu przez bibliotek Boost Spirit poniszy w peni
poprawny kod C++ dziaa w zasadzie identycznie.
% *
 9%  * :;  '('  %9%  (* :; 
&  9%  * :;  ','  %9%  ,* :; 
& 9%  * :;
!
 *
 -9  * :;  '.'  9  .* :; 
&  -9  * :;  ' '  9  * :; 
& -9  * :;
!
- *
59-  * :;
&  ''  %9-  * :;  '' 
!

Kade przypisanie zapamituje obiekt funkcji, ktry analizuje i oblicza element gramatyki podany po prawej stronie. Zachowanie kadego zapamitanego obiektu funkcyjnego

18

Rozdzia 1. Wprowadzenie

w momencie wywoania jest w peni okrelone jedynie przez typ wyraenia uytego
do jego wykonania. Typ kadego wyraenia jest obliczany przez metaprogram
zwizany z poszczeglnymi operatorami.
Podobnie jak YACC biblioteka Spirit jest metaprogramem generujcym analizatory
skadniowe dla podanej gramatyki. Jednak w odrnieniu od YACC Spirit definiuje
swj jzyk specjalistyczny jako podzbir samego jzyka C++. Jeli jeszcze nie dostrzegasz tego powizania, nic nie szkodzi. Po przeczytaniu niniejszej ksiki na
pewno wszystko stanie si oczywiste.

1.5. Dlaczego metaprogramowanie?


Jakie s zalety metaprogramowania? Z pewnoci istniej prostsze sposoby rozwizania przedstawionych tutaj problemw. Przyjrzyjmy si dwm innym podejciom i przeanalizujmy ich zastosowanie pod ktem interpretacji wartoci binarnych i konstrukcji
analizatorw skadniowych.

1.5.1. Pierwsza alternatywa


obliczenia w trakcie dziaania programu
Chyba najprostsze podejcie zwizane jest z wykonywaniem oblicze w trakcie dziaania
programu zamiast na etapie kompilacji. Mona w tym celu wykorzysta jedn z implementacji funkcji  z poprzedniej czci rozdziau. System analizy skadniowej
mgby dokonywa interpretacji gramatyki w trakcie dziaania programu, na przykad
przy pierwszym zadaniu analizy skadniowej.
Oczywistym powodem wykorzystania metaprogramowania jest moliwo wykonania
jak najwikszej liczby zada jeszcze przed uruchomieniem programu wynikowego
w ten sposb uzyskuje si szybsze programy. W trakcie kompilacji gramatyki YACC
dokonuje analizy i optymalizacji tabeli generacji, co w przypadku wykonywania tych
zada w trakcie dziaania programu zmniejszyoby ogln wydajno. Podobnie, poniewa  wykonuje swoje zadanie w trakcie kompilacji,
  jest dostpna
jako staa w trakcie kompilacji, a tym samym kompilator moe j bezporednio zamieni na kod obiektu, zaoszczdzajc wyszukania w pamici, gdy zostanie uyta.
Bardziej subtelny, ale i waniejszy argument przemawiajcy za metaprogramowaniem
wynika z faktu, i wynik oblicze moe wej w znacznie gbsz interakcj z docelowym jzykiem. Na przykad rozmiar tablicy mona poprawnie okreli na etapie
kompilacji tylko jako sta, na przykad 
  nie mona tego zrobi
za pomoc wartoci zwracanej przez funkcj. Akcje zawarte w nawiasach klamrowych gramatyki YACC mog zawiera dowolny kod C lub C++, ktry zostanie wykonany jako cz analizatora skadniowego. Takie rozwizanie jest moliwe tylko
dlatego, e akcje s przetwarzane w trakcie kompilacji gramatyki i s przekazywane
do docelowego kompilatora C++.

1.5. Dlaczego metaprogramowanie?

19

1.5.2. Druga alternatywa analiza uytkownika


Zamiast wykonywa obliczenia w trakcie kompilacji lub dziaania programu, wykonujemy wszystko rcznie. Przecie przeksztacanie wartoci binarnych na ich odpowiedniki
szesnastkowe jest powszechnie stosowan praktyk. Podobnie ma si sprawa z krokami
przeksztace wykonywanymi przez program YACC lub bibliotek Boost Spirit.
Jeli alternatyw jest napisanie metaprogramu, ktry zostanie wykorzystany tylko raz,
mona argumentowa, i analiza uytkownika jest wygodniejsza atwiej skonwertowa
rcznie warto binarn na szesnastkow ni pisa wykonujcy to samo zadanie metaprogram. Jeeli jednak wystpie takiej sytuacji bdzie kilka, wygoda bardzo szybko
przesuwa si w stron przeciwn. Co wicej, po napisaniu metaprogramu mona go
rozpowszechni, aby inni programici rwnie mogli wygodniej pisa programy.
Niezalenie od liczby uy metaprogramu zapewnia on uytkownikowi wiksz si
wyrazu kodu, gdy mona okreli wynik w formie najlepiej tumaczcej jego dziaanie. W kontekcie, gdzie wartoci poszczeglnych bitw maj due znaczenie, znacznie wikszy sens ma napisanie 
  ni  lub tradycyjne .
Podobnie kod w jzyku C dla rcznie napisanego analizatora kodu na og zasania
logiczne zwizki midzy poszczeglnymi elementami gramatyki.
Poniewa ludzie s uomni, a logik metaprogramu wystarczy napisa tylko raz, wynikowy program ma wiksz szans by poprawnym i atwiej modyfikowalnym.
Rczna zamiana wartoci binarnych zwiksza prawdopodobiestwo popenienia bdu, bo jest bardzo nudna. Dla odrnienia rczne tworzenie tabel analizy skadniowej
jest tak niewdzicznym zadaniem, i unikanie w tej kwestii bdw jest powanym
argumentem za korzystaniem z generatorw takich jak YACC.

1.5.3. Dlaczego metaprogramowanie w C++?


W jzyku takim jak C++, gdzie jzyk specjalistyczny stanowi po prostu podzbir jzyka
uywanego w pozostaej czci programu, metaprogramowanie jest szczeglnie wygodne i uyteczne.
 Uytkownik moe od razu korzysta z jzyka specjalistycznego bez uczenia

si nowej skadni lub przerywania ukadu pozostaej czci programu.


 Powizanie metaprogramw z pozostaym kodem, w szczeglnoci innymi

metaprogramami, staje si bardziej pynne.


 Nie jest wymagany aden dodatkowy krok w trakcie kompilacji (jak ma

to miejsce w przypadku YACC).


W tradycyjnym programowaniu powszechne s starania o odnalezienie zotego rodka
midzy wyrazistoci, poprawnoci a wydajnoci kodu. Metaprogramowanie uatwia
przerwanie tej klasycznej szarady i przeniesienie oblicze wymaganych do uzyskania
wyrazistoci i poprawnoci do etapu kompilacji.

Rozdzia 1. Wprowadzenie

20

1.6. Kiedy stosowa


metaprogramowanie?
Przedstawilimy kilka odpowiedzi na pytanie dlaczego metaprogramowanie i kilka
przykadw wyjaniajcych, jak dziaa metaprogramowanie. Warto jeszcze wyjani,
kiedy warto je stosowa. W zasadzie ju przedstawilimy wikszo najwaniejszych
kryteriw stosowania metaprogramowania szablonami. Jeli spenione s dowolne
trzy z poniszych warunkw, warto zastanowi si nad rozwizaniem wykorzystujcym
metaprogramowanie.
 Chcesz, aby kod zosta wyraony w kategoriach dziedziny problemowej.

Na przykad chcesz, by analizator skadni przypomina gramatyk formaln,


a nie zbir tabel i podprocedur, lub dziaania na tablicach przypominay
notacj znan z obiektw macierzy lub wektorw, zamiast stanowi
zbir ptli.
 Chcesz unikn pisania duej iloci podobnego kodu implementacyjnego.
 Musisz wybra implementacj komponentu na podstawie waciwoci

jego parametrw typu.


 Chcesz skorzysta z zalet programowania generycznego w C++, na przykad

statycznego sprawdzania typw i dostosowywania zachowa bez utraty


wydajnoci.
 Chcesz to wszystko wykona w jzyku C++ bez uciekania si

do zewntrznych narzdzi i generatorw kodu rdowego.

1.7. Dlaczego biblioteka


metaprogramowania?
Zamiast zajmowa si metaprogramowaniem od podstaw, bdziemy korzystali z wysokopoziomowej pomocy biblioteki MPL (Boost Metaprogramming Library). Nawet jeli kto nie wybra tej ksiki w celu zapoznania si ze szczegami MPL, sdzimy, e
czas powicony na jej nauk nie pjdzie na marne, gdy atwo j wykorzysta w codziennej pracy.
1. Jako. Wikszo programistw uywajcych komponentw

metaprogramowania szablonami traktuje je cakiem susznie jako


szczegy implementacyjne wprowadzane w celu uatwienia wikszych
zada. Dla odrnienia, autorzy MPL skupili si na wykonaniu uytecznych
narzdzi wysokiej jakoci. Oglnie komponenty z biblioteki s bardziej
elastyczne i lepiej zaimplementowane ni te, ktre wykonaoby si samemu
w celu przeprowadzenia innych zada. Co wicej, przysze wydania
z pewnoci bd ulepszane i optymalizowane.

1.7. Dlaczego biblioteka metaprogramowania?

21

2. Ponowne uycie. Wszystkie biblioteki hermetyzuj kod jako komponent

wielokrotnego uytku. Co wicej, dobrze zaprojektowana biblioteka oglna


zapewnia szkielet pojciowy mentalnego modelu rozwizywania pewnych
problemw. Podobnie jak standardowa biblioteka jzyka C++ dostarcza
iteratory i protok obiektw funkcyjnych, biblioteka MPL zapewnia iteratory
typw i protok metafunkcyjny. Dobrze wykonany szkielet pozwala
programicie skupi si na decyzjach projektowych i szybkim wykonaniu
waciwego zadania.
3. Przenono. Dobra biblioteka potrafi gadko przej przez niuanse rnic

w platformach sprztowych. Cho w teorii aden z metaprogramw jzyka


C++ nie powinien mie problemw z przenonoci, rzeczywisto jest inna
nawet po 6 latach od standaryzacji. Nie powinno to jednak dziwi szablony
C++ to najbardziej zoony aspekt tego jzyka programowania, ktry
jednoczenie stanowi o sile metaprogramowania C++.
4. Zabawa. Wielokrotne pisanie tego samego kodu jest wyjtkowo nudne.

Szybkie poczenie komponentw wysokiego poziomu w czytelne, eleganckie


rozwizanie to czysta zabawa! Biblioteka MPL redukuje nud, eliminujc
potrzeb powtarzania najbardziej typowych wzorcw metaprogramowania.
Przede wszystkim elegancko unika si specjalizacji przerywajcych i jawnych
rekurencji.
5. Wydajno wytwarzania. Poza satysfakcj personelu zdrowie projektw

zaley rwnie od przyjemnoci czerpanej z programowania. Gdy programista


przestaje mie frajd z programowania, staje si zmczony i powolny bdny
kod jest bardziej kosztowny od kodu pisanego dobrze, ale powoli.
Jak atwo si przekona, biblioteka MPL jest pisana zgodnie z tymi samymi zasadami,
ktre przywiecaj tworzeniu innych bibliotek. Wydaje nam si, e jej pojawienie si
jest zwiastunem, i metaprogramowanie szablonami jest gotowe opuci pracownie
badawcze i zacz by stosowane przez programistw w codziennej pracy.
Chcielibymy zwrci szczegln uwag na czwarty z przedstawionych punktw. Biblioteka MPL nie tylko uatwia korzystanie z metaprogramowania, ale rwnie czyni
je czyst przyjemnoci. Mamy nadziej, e innym osobom uczenie si jej przyniesie
tyle radoci, co nam przynioso jej tworzenie i wykorzystywanie.

You might also like