Modern C++
• tech • 567 słów • 3 minuty czytania
W nawiązaniu do poprzedniej notatki, niejakim uzupełnieniem przedstawionych tam informacji i zapowiedzi o dzieleniu się głębszymi przemyśleniami i odczuciami jakimi napełnił mnie kolejny przeprowadzony code-review, będą notatki przedstawiające nieco bardziej zaawansowane aspekty i techniki używane w C++.
Mam tu na myśli notatki traktujące o tytułowym “modern C++”, czyli nowoczesnym i zaawansowanym C++, gdzie głównie wykorzystywane są wzorce i metaprogramowanie. Nie powinno także zabraknąć innych zaawansowanych funkcji oferowanych przez język. Większość będzie silnie powiązana z maksymalnym wykorzystaniem biblioteki STL i boost.
Wszystkie informacje zawarte w poprzedniej notce dotyczące technicznych i logicznych aspektów notatek jakie będą się pojawiać tutaj również obowiązują. Oczywiście będzie to w trochę innej formie, acz zbliżonej, bo jak już mówiłem “nie chcę i nie będę nikogo uczył programowania”. Nie to jest moich celem.
Głównym moim zamiarem jest zaprezentowanie ciekawych, praktycznych rozwiązań i technik jakie sam niedawno użyłem we własnym kodzie, zaimplementowałem lub poznałem. Czasem będą trafiać się też typowe i proste elementy lub nawet podstawy programowania i metaprogramowania w C++. Wszystko będzie przedstawione w szczegółach (czasem większych, czasem mniejszych) opisujących “jak i dlaczego” to ma szanse działać i działa w rzeczywistości.
Jako przykład można podać asercje statyczne, wiemy jak, i po co, i dlaczego stosować, wszyscy to robimy, ale na pewno nie wszyscy wiedzą jak i dlaczego to działa - porównanie wyniku operacji operatora sizeof
z czymś tam pozwala nam wybiorczo wstrzymać proces kompilacji i czasem wypluć czytelny powód. To prawie jak magia!
Innym przykładem ciekawego rozwiązania, może być kontrola konkretyzacji wzorca funkcji za pomocą listy typów. Wtedy próba skonkretyzowania wzorca nieodpowiednim typem (dla którego z jakiś powodów nie chcemy konkretyzować wzorca) kompilator zakończy się przerwaniem procesu budowania aplikacji.
Wielką zaletą metaprogramwoania jest “zmuszanie” kompilatora do wygenerowania odpowiedniego, według naszych wytycznych, kodu. W małym skrócie, używamy wzorców w taki sposób, że kompilator w trakcie kompilacji traktuje je jako “program” do wykonania a wynik operacji - kod, jest często dosyć bardzo zoptymalizowany i wydajny, głównie dzięki rozwijaniu kodu wzorców. Często dzięki wzorcom i metaprogramowaniu możemy “wyjść” poza bariery i ograniczenia języka. No, ale to nie miejsce do wymieniania i zachwycania się możliwościami i zaletami tej techniki.
Akurat jakiś czas temu sam zacząłem się “bawić” w metaprogramowanie i nieco bardziej zaawansowane użycie wzorców w swoich kodach. Takie wykorzystanie ich do czegoś więcej, niż implementacji kolejnego generycznego typu lub klasy. W wielu miejscach pozwala to ułatwić i usprawnić pracę, a nawet lepiej i łatwiej odzwierciedlić logiczną koncepcję i design naszego projektu lub algorytmu.
Początkującym adeptom sztuki metaprogramowania, wzorców i zaawansowanych technik, mogę polecić lekturę kilku książek. Większości niestety niemiałem okazji przeczytać i to pomimo, że kilka z nich posiadam. Jedyne co mi się udało to je pobieżnie przejrzeć w oryginalnym wydaniu w wersji angielskiej i wydają się naprawdę wartościowym materiałem.
Moja mała uwaga co do książek. Osobiście uważam, że z książek nie można się nauczyć programowania. Za to można poznać ciekawe informacje odnośnie danego tematu, poznać podstawy teoretyczne, spojrzenie na problemy i sposoby ich rozwiązywania, przez innych, często wybitnych programistów. Natomiast, aby się nauczyć musimy sami działać.
Polecana bibliografia:
- Nowoczesne projektowanie w C++, Andrei Alexandrescu
- Język C++. Metaprogramowanie za pomocą szablonów, David Abrahams, Aleksey Gurtovoy
- C++. Szablony. Vademecum profesjonalisty, David Vandevoorde, Nicolai M. Josuttis
- Więcej niż C++. Wprowadzenie do bibliotek Boost, Björn Karlsson
- Zaawansowane CPP, wazniak.mimuw.edu.pl
Mam nadzieję, że notatki powstające na fali uniesień przeglądem kodu i prezentacja stosowanych rozwiązań w nowoczesnym C++ będą ciekawe, a nie jedna osoba z nich skorzysta lub się czegoś nowego nauczy ;)
Komentarze (2)
Tak - nowoczesne metaprogramowanie jest fajne, ale:
Czas kompilacji programów wykorzystujących templejty znacznie się wydłuża. Odczułem to boleśnie gdy przeszedłem na boosta.
Komunikaty o błędach są kosmicznie długie: jeden komunikat wygenerowany przez g++ może miec ponad ekran i zawiera cały “stos” wywołań templejta. Odnalezienie się w tym gąszczu wymaga nieco ćwiczeń.
A tak w ogóle to fajny ten blog :-)
To prawda, ale obecnie kompilatory już nieco lepiej prezentują błędy z szablonami. Gorzej jak gdzieś dostaniemy taki surowy, niesformatowany, np. w call stacku, to wtedy “droga przez mękę”. Szczególnie daje to o sobie znać w wielu zagnieżdżeniach szablonów, czyli dzień powszedni w przypadku boosta.
Milo mi słyszeć, ze komuś się podoba ;)