Cyfroteka.pl

klikaj i czytaj online

Cyfro
Czytomierz
00413 006960 19023706 na godz. na dobę w sumie
Opus magnum C++. Misja w nadprzestrzeń C++14/17. Tom 4 - książka
Opus magnum C++. Misja w nadprzestrzeń C++14/17. Tom 4 - książka
Autor: Liczba stron: 280
Wydawca: Helion Język publikacji: polski
ISBN: 978-83-283-6587-2 Data wydania:
Lektor:
Kategoria: ebooki >> komputery i informatyka >> programowanie >> c++ - programowanie
Porównaj ceny (książka, ebook (-30%), audiobook).

C++ - mierz wysoko!

C++ to jeden z najpopularniejszych i najpotężniejszych języków programowania. Stanowi punkt wyjścia dla wielu innych języków, które odziedziczyły po nim składnię i liczne możliwości, dzięki czemu można śmiało stwierdzić, że znajomość C++ otwiera drzwi do świata nowoczesnego programowania i jest podstawą na wymagającym rynku pracy w branży informatycznej. Czasy się zmieniają, lecz to C++ jest wciąż wybierany wszędzie tam, gdzie liczą się możliwości, elastyczność, wydajność i stabilność.

Książka, którą trzymasz w rękach, to kontynuacja genialnego kompendium Opus magnum C++11. Programowanie w języku C++. Autor, wybitny specjalista z ogromnym doświadczeniem w międzynarodowych projektach i twórca niezwykle popularnego podręcznika Symfonia C++, postanowił uzupełnić swoje dzieło o zagadnienia, dla których zabrakło miejsca w poprzednich tomach. Jeśli chcesz poszerzyć wiedzę na temat szablonów oraz poznać możliwości najnowszych standardów języka C++, nie mogłeś lepiej trafić!

Rusz w kolejną misję z C++ na pokładzie!

Znajdź podobne książki Ostatnio czytane w tej kategorii

Darmowy fragment publikacji:

Wszelkie prawa zastrzeżone. Nieautoryzowane rozpowszechnianie całości lub fragmentu niniejszej publikacji w jakiejkolwiek postaci jest zabronione. Wykonywanie kopii metodą kserograficzną, fotograficzną, a także kopiowanie książki na nośniku filmowym, magnetycznym lub innym powoduje naruszenie praw autorskich niniejszej publikacji. Wszystkie znaki występujące w tekście są zastrzeżonymi znakami firmowymi bądź towarowymi ich właścicieli. Autor oraz Wydawnictwo Helion SA dołożyli wszelkich starań, by zawarte w tej książce informacje były kompletne i rzetelne. Nie biorą jednak żadnej odpowiedzialności ani za ich wykorzystanie, aniza związane z tym ewentualne naruszenie praw patentowych lub autorskich. Autor oraz Wydawnictwo Helion SA nie ponoszą również żadnej odpowiedzialności za ewentualne szkody wynikłe z wykorzystania informacji zawartych w książce. Redaktor prowadzący: Małgorzata Kulik Projekt okładki i opracowanie graficzne książki: Jerzy Grębosz Zdjęcie Mgławicy Orzeł w grafice na okładce oraz zdjęcia łazika Curiosity i powierzchni Marsa – wykorzystane w tytułach rozdziałów – dzięki uprzejmości NASA. Wydanie pierwsze ISBN: 978-83-283-6587-2 Copyright © Jerzy Grębosz 2020 Printed in Poland Helion SA ul. Kościuszki 1c, 44-100 GLIWICE tel. 32 231 22 19, 32 230 98 63 e-mail: helion@helion.pl WWW: http://helion.pl (księgarnia internetowa, katalog książek) Drogi Czytelniku! Jeżeli chcesz ocenić tę książkę, zajrzyj pod adres http://helion.pl/user/opinie/opc144 Możesz tam wpisać swoje uwagi, spostrzeżenia, recenzję. Kody źródłowe wybranych przykładów dostępne są pod adresem: ftp://ftp.helion.pl/przyklady/opc144.zip • Kup książkę • Poleć książkę • Oceń książkę • Księgarnia internetowa • Lubię to! » Nasza społeczność Spis treœci V Spis treœci 0 Proszê tego nie czytaæ!.........................................................................1 0.1 Wyruszamy na kolejn¹ wyprawê!..........................................................................................1 1 Sza b lony o zmiennej liczbie parametrów ...........................................3 Szablon funkcji o zmiennej liczbie parametrów (i argumentów)...........................................4 1.1 1.2 Jak dobraæ siê do argumentów tkwi¹cych w pakiecie?........................................................11 Ciekawe sza b lony zwracaj¹ce rezultat ............................................................................16 1.2.1 Szablon klas o dowolnej (zmiennej) liczbie parametrów.....................................................18 1.3 Trzy rodzaje pakietów parametrów szablonu ......................................................................24 1.4 Pakiet szablonu bêd¹cy pakietem wartoœci .....................................................................25 1.4.1 1.5 Argumenty pakietu odbierane przez wartoœæ, referencjê, adres..........................................30 Rozwiniêcie wed³ug wzorca (czyli rozwiniêcie „z kontekstem”) ........................................31 1.6 Rozwiniêcie pakietu typów w klamrowej liœcie inicjalizatorów..........................................34 1.7 £atwe narzêdzie do wypisania argumentów....................................................................34 1.7.1 Rozwiniêcie pakietu na liœcie parametrów aktualnych innego szablonu .............................36 1.8 1.9 Gdzie mo¿na umieœciæ wyra¿enia rozwijaj¹ce pakiet parametrów ......................................39 Æwiczenia ............................................................................................................................39 1.10 2 Cechy jêzyka wprowadzone do standardu C++14 ...........................43 2.1 Zapis dwójkowy sta³ych dos³ownych..................................................................................43 Separatory cyfr w sta³ych dos³ownych ................................................................................44 2.2 Wypisywanie liczb w postaci binarnej............................................................................45 2.2.1 Wczytywanie liczb dwójkowych strumieniem wejœciowym...........................................48 2.2.2 Kompilator rozpoznaje typ rezultatu funkcji .......................................................................50 2.3 Deklaracja typu rezultatu decltype(auto) ...............................................................................52 2.4 Przyk³ad zastosowania konstrukcji decltype(auto) w sza b lonie funkcji............................55 2.4.1 Szablon definicji zmiennej ..................................................................................................59 2.5 Jak to drzewiej bywa³o, czyli œwiat bez szablonów zmiennych ......................................64 2.5.1 Teraz zobaczysz, jak prosto siê to robi z C++14.............................................................71 2.5.2 2.5.3 Ciekawe zastosowanie: sprawdzenie cech charakteru danego typu ................................72 Lubiê, nie lubiê... ............................................................................................................77 2.5.4 Dwa usprawnienia...........................................................................................................80 2.5.5 Realizacja tego pomys³u w programie ...........................................................................81 2.5.6 Prze³adowanie globalnych operatorów new, new[ ], delete i delete[ ].....................................86 2.6 2.7 Nowoœci C++14 w wyra¿eniach lambda .............................................................................94 Przyk³ad uogólnionego wyra¿enia lambda......................................................................94 2.7.1 Przyk³ad defi ni cji obiektu na liœcie wychwytywania i jego ini cja li za cja ........................96 2.7.2 2.7.3 Przyk³ad wychwycenia na zasadzie przeniesienia (move) ..............................................99 Poleć książkęKup książkę VI 2.8 2.8.1 2.8.2 2.9 2.9.1 2.9.2 2.9.3 2.9.4 2.9.5 2.9.6 2.9.7 2.9.8 2.9.9 2.9.10 2.10 2.11 Spis treœci C++14 a funkcje constexpr .................................................................................................104 Zniesienie wielu ograniczeñ w ciele funkcji constexpr ..................................................104 Funkcje sk³adowe constexpr w C++14 nie s¹ ju¿ auto ma ty cz nie const .........................110 Atrybuty.............................................................................................................................111 Nowy atrybut [[dep re cated]] wprowadzony w C++14 ....................................................112 Oznaczenie wybranej funkcji jako przestarza³ej ...........................................................113 Argu men t funkcji uznany za przestarza³y .....................................................................114 Przestarza³e niestatyczne sk³adniki klasy: funkcja sk³adowa i dana sk³adowa..............114 Obie k t oznaczony jako przestarza³y..............................................................................115 dep re cated a zbiorcza defi ni cja kilku zmiennych (z ewentualn¹ ini cja li za cj¹) ..............116 Typy, które uznajemy za przestarza³e ...........................................................................116 Przestarza³e synonimy typów (w instrukcjach typedef i us ing) ......................................118 Oznaczanie atrybutem [[dep re cated]] specjalizacji szablonu klasy .................................118 Oznaczanie atrybutem [[dep re cated]] specjalizacji szablonu funkcji ..............................119 Przewrotu nie by³o.............................................................................................................119 Æwiczenia ..........................................................................................................................119 3 Cechy jêzyka wprowadzone do standardu C++17 .........................123 Specyfikacja wyj¹tków staje siê czêœci¹ typu funkcji........................................................123 3.1 Technika „pomijanie kopiowania” bywa teraz obowi¹zkiem kompilatora........................128 3.2 Przydomek alignas a operatory new i delete........................................................................134 3.3 Prze³adowanie globalnych new i de lete uwzglêdniaj¹ce wyrównanie adresów .............135 3.3.1 Jak prze³adowaæ wyrównuj¹ce ope ra tory new/de lete na u¿ytek wybranej klasy............141 3.3.2 Porz¹dek obliczania sk³adników w z³o¿onych wyra¿eniach – nareszcie ustalony ............144 3.4 Sta³a znakowa typu u8 .......................................................................................................146 3.5 Szesnastkowy zapis liczb zmiennoprzecinkowych............................................................147 3.6 Wypisywanie i wczytywanie zmiennoprzecinkowych liczb szesnastkowych...............149 3.6.1 3.7 Wyra¿enia posk³adane w harmonijkê – u³atwienie pracy z pakietem argumentów...........152 Pierwszy przyk³ad u¿ycia wyra¿enia harmonijkowego w sza b lonie.............................152 3.7.1 Harmonijka z dodatkowym wyra¿eniem pocz¹tkowym ...............................................155 3.7.2 Cztery formy wyra¿enia harmonijkowego ....................................................................157 3.7.3 Kontekst wyra¿enia harmonijkowego – przyk³ad .......................................................159 3.7.4 Dozwolone s³owo auto w deklaracji template auto .........................................................161 3.8 Kompilator rozpoznaje typ parametrów klasy szablonowej .............................................166 3.9 Wektory czego innego ni¿ widaæ ..................................................................................170 3.9.1 Instrukcja if constexpr – prawie jak kompilacja warunkowa...............................................173 3.10 Instrukcja if constexpr rozwi¹zuje prob lem „lubianych” i „nielubianych” typów ..........176 3.10.1 3.11 Wyra¿enia inicjalizuj¹ce w instrukcjach if i switch.............................................................179 Dowi¹zania strukturalne, czyli ³atwe „siêganie do sk³adników” .......................................182 3.12 Dowi¹zanie do tablic zbudowanych na bazie klasy std::ar ray........................................184 3.12.1 £atwe siêganie do sk³adników struktur/klas..................................................................185 3.12.2 Przystosowanie naszej klasy do obs³ugi dekla ra cji dowi¹zañ.......................................192 3.12.3 3.12.4 Przystosowanie cudzej klasy do obs³ugi dekla ra cji dowi¹zañ ......................................198 Operator preprocesora zwany __has_include ......................................................................201 3.13 Nowe atrybuty: maybe_unused, fallthrough i nodiscard ........................................................203 3.14 Atrybut [[maybe_un used]] ...............................................................................................205 3.14.1 Atrybut [[fallthrough]] u¿ywany w instrukcji switch .........................................................208 3.14.2 Atrybut [[nodiscard]] – nie zlekcewa¿ mnie... .................................................................210 3.14.3 Typ std::byte do operacji na surowych blokach pamiêci ....................................................213 3.15 3.16 Modyfikacje istniej¹cych cech jêzyka ...............................................................................222 3.17 RozluŸnienie zasady inicjalizowania typów wyliczeniowych ...........................................223 3.18 Modyfikacja deklaracji static_assert...................................................................................224 Prostszy sposób zapisu zagnie¿d¿onych przestrzeni nazw ................................................225 3.19 Dozwolone s³owo typename w parametrze okreœlaj¹cym inny szablon .............................229 3.20 Poleć książkęKup książkę Spis treœci VII Dla zakresowej pêtli for funkcje begin i end mog¹ zwracaæ odmienne typy.......................233 3.21 Rozwiniêcie pakietu mo¿liwe nawet w deklaracji using ....................................................239 3.22 Nowe zasady auto-rozpoznawania typu obiektów maj¹cych inicjalizacjê klamrow¹ ........245 3.23 3.24 W C++17 agregat mo¿e byæ nawet klas¹ pochodn¹ ..........................................................247 Zmiana typu rezultatu funkcji std::uncaught_exception .......................................................250 3.25 3.26 Æwiczenia ..........................................................................................................................254 4 Pos³owie – czyli C++20 ante portas.................................................264 Skorowidz ................................................................................................265 Poleć książkęKup książkę Poleć książkęKup książkę 0 . P r o s z ê t e g o n i e c z y t a æ ! Wyruszamy na kolejn¹ wyprawê! 1 0 Proszê tego nie czytaæ! 0.1 Wyruszamy na kolejn¹ wyprawê! Ta ksi¹¿ka jest kontynuacj¹ ksi¹¿ki Opus magnum C++11. Jeœli przeczyta³eœ Opus, to znaczy, ¿e jesteœmy ju¿ od dawna przyjació³mi. Nie muszê siê wiêc przedstawiaæ, po prostu powiem: Witaj, stary przyjacielu! Tak siê cieszê, ¿e znowu do mnie zajrza³eœ. W tej kolejnej ksi¹¿ce chcia³bym Ciê zabraæ w te rejony C++, o których Opus jeszcze nie mówi³. Opowiem Ci tutaj o niezwykle ciekawych zmianach w jêzyku C++ wprowadzonych przez standardy zwane potocznie C++14 i C++17. W rozmowach z Czytelnikami czêsto pytam ich z obaw¹, czy aby Opus nie przyt³acza ich swoj¹ obszernoœci¹. To w koñcu oko³o 1600 stron. Na to oni odpowiadaj¹, ¿ebym siê tym zupe³nie nie przejmowa³, bo dla nich to czysta przyjemnoœæ. Gdyby nawet ksi¹¿ka mia³a 500 stron wiêcej, dla nich by³oby to po prostu 500 stron wiêcej niezwyk³ej intelektualnej przygody. Zastanawiam siê, czy oni mnie czasem nie wkrêcaj¹... Z powodu tych obaw na wszelki wypadek pomin¹³em kiedyœ w Opusie zagadnienie sza blo nów o zmiennej (dowolnej) liczbie parametrów. Po prostu wtedy wyda³o mi siê to zbyt szczegó³owe. Gdy w rozdziale o szablonach napisa³em: „Koñczê ten rozdzia³ z poczuciem, ¿e nie wy - czer pu je on ca³oœci rozleg³ego zagadnienia” – mia³em wówczas na myœli w³aœnie te szablony. Co siê odwlecze... No i mo¿e do dziœ nikt by siê nie zorientowa³, ¿e tê sprawê pomin¹³em, ale w standar - dzie C++17 pojawi³y siê tak zwane wyra¿enia harmonijkowe (fold expressions). U ich pod³o¿a le¿¹ w³aœnie te opuszczone przeze mnie szablony o zmiennej liczbie para - metrów. Nie ma rady, muszê wiêc teraz to nadrobiæ. Tê ksi¹¿kê rozpoczyna wobec tego krótki, ale ciekawy rozdzia³ na ten temat. Teraz myœlê, ¿e nawet dobrze siê sta³o, bo obecnie – gdy masz ju¿ pewien dystans czasowy do Opusu – zagadnienie to wyda Ci siê ³atwe. Po tym rozdziale nastêpuje rozdzia³ przedstawiaj¹cy nowoœci jêzyka wprowadzone przez standard C++14. W kolejnym – opis nowych zagadnieñ wprowa dzo nych przez standard C++17. Poleć książkęKup książkę ! æ a t y z c e i n o g e t ê z s o r P . 0 2 Internetowe wsparcie Wyruszamy na kolejn¹ wyprawê! Zapewne niejedno da siê w tej ksi¹¿ce poprawiæ. Jeœli bêdziesz mia³ jakieœ uwagi, to proszê, przyœlij mi je poczt¹ elektroniczn¹ na adres: jerzy.grebosz@ifj.edu.pl Z góry wyra¿am moj¹ wdziê cz noœæ za nawet najdrobniejsze uwagi. Proszê, napisz nawet o zauwa¿onych b³êdach literowych czy o swoich odczuciach, ¿e jakiœ fragment jest niejasny albo stanowczo za trudny. Kod Ÿród³owy przyk³adowych programów z tej ksi¹¿ki mo¿na pobraæ ze strony WWW wydawnictwa, a tak¿e z mojej strony WWW w internecie. Obecny adres mojej strony to: https://www.ifj.edu.pl/private/grebosz/ Nawet jeœli ten adres siê kiedyœ zmieni, ³atwo bêdzie znaleŸæ now¹ lokalizacjê za pomoc¹ internetowej wyszukiwarki, podaj¹c has³o Misja w nadprzestrzeñ C++14/17 lub moje nazwisko. Na mojej stronie WWW mo¿esz te¿ szukaæ odpowiedzi do æwiczeñ, które s¹ zamiesz - czone na koñcu poszczególnych rozdzia³ów tej ksi¹¿ki. Na stronach WWW zawie - raj¹ cych materia³y uzupe³niaj¹ce do tej ksi¹¿ki znajdziesz te¿ ewentualn¹ erratê tworzon¹ na bie¿¹co z uwag nadsy³anych przez Czytelników. A zatem wyruszamy razem w kolejn¹ wielk¹ przygodê, do gwiazd. Semper in altum! Poleć książkęKup książkę Poleć książkęKup książkę 94 2.7 Nowoœci C++14 w wyra¿eniach lambda @ Nowoœci C++14 w wyra¿eniach lambda O wyra¿eniach lambda rozmawialiœmy w Opus magnum w rozdziale 30. Teraz zapo - zna my siê z dwoma ciekawymi cechami wprowadzonymi przez standard C++14. S¹ to: 1) uogólnione wyra¿enia lambda, 2) definicja (na liœcie wychwytywania) lokalnego obiektu, maj¹cego swoj¹ inicjalizacjê. 2.7.1 Zanim zobaczymy te cechy w przyk³adowych programach, kilka zdañ wyjaœnienia. Przyk³ad uogólnionego wyra¿enia lambda Mówi¹c najproœciej, w C++11 argumenty formalne wyra¿enia lambda musia³y byæ œciœle okreœlonego typu. Tymczasem... Standard C++14 pozwala, by typ argumentu formalnego naszego wyra¿e - nia lambda by³ parametrem. Robimy to, okreœlaj¹c typ danego parametru s³owem auto. Dziêki temu nasze wyra¿enie lambda staje siê jakby sza blo - nem funkcji lambda o danej nazwie. W poni¿szym programie zobaczysz, jakie to proste. wIII `$ - re set numerkow #include iostream using namespace std; //***************************************************************************************************************** int main() { // wytworzenie zwyk³ego wyra¿enia lambda C++11 auto czy_mniejsze_int = [ ] (int m, int k) { return m k; }; 1 o d e n o z d a w o r p w a k y z ê j y h c e C . 2 4 1 + + C u d r a d n a t s cout boolalpha; 2 cout Czy (5 2) ? czy_mniejsze_int(5, 2) endl; 3 cout Czy (5.1 5.9) ? czy_mniejsze_int(5.1, 5.9) endl; // niestety! 4 // C++14 // wytworzenie uogólnionego wyra¿enia lambda auto czy_mniejsze_uniwersalne = [ ] (auto m, auto k) { return m k; }; cout Czy (5 2) ? czy_mniejsze_int(5, 2) endl; cout Czy (5.1 5.9) ? czy_mniejsze_int(5.1, 5.9) endl; // to dzia³a nawet na znakach cout Czy ( a b ) ? czy_mniejsze_uniwersalne( a , b ) endl; cout Czy ( b a ) ? czy_mniejsze_uniwersalne( b , a ) endl; cout Wolno nawet nawet porownac wartosci roznych typow\n ; cout Czy (3 3.14 ) ? czy_mniejsze_uniwersalne(3, 3.14) endl; cout Znak p ma kod liczbowy: int( p ) endl; cout Czy ( p 111) ? czy_mniejsze_uniwersalne( p , 111) endl; cout Czy ( p 113.5) ? czy_mniejsze_uniwersalne( p , 113.5) endl; } 5 6 7 8 9 Ba Bb Poleć książkęKup książkę Nowoœci C++14 w wyra¿eniach lambda 95 Na ekranie pojawi siê taki tekst: Czy (5 2) ? false Czy (5.1 5.9) ? false Czy (5 2) ? false Czy (5.1 5.9) ? false Czy ( a b ) ? true Czy ( b a ) ? false Wolno nawet nawet porownac wartosci roznych typow Czy (3 3.14 ) ? true Znak p ma kod liczbowy: 112 Czy ( p 111) ? false Czy ( p 113.5) ? true 3 4 6 7 9 Ba Bb Naj pierw przy pom nienie Jak pamiêtamy z C++11, wyra¿enie lambda najczêœciej wpisujemy wprost w po trzeb - n¹ nam instrukcjê. Zostaje ono u¿yte przez tê instrukcjê, a potem staje siê niepotrzebne. Gdybyœmy jednak chcieli skorzystaæ z danego wyra¿enia lambda kilka krotnie (w kilku innych instrukcjach), mo¿emy to zrobiæ, nadaj¹c mu nazwê. W praktyce nadanie nazwy polega na tym, ¿e definiujemy „obiekt lambda” o okreœlo nej nazwie i inicja li - zujemy go wymyœlonym przez siebie wyra¿eniem lambda. auto nazwa_obiektu_lambda = wyra¿enie_lambda; Abyœmy siê nie musieli g³owiæ, jakiego typu jest nasze wyra¿enie lambda, stosujemy zastêpcze s³owo kluczowe auto. Nie bêdê rozwija³ tego zagadnienia, bo o tej sprawie rozmawialiœmy w Opusie (§30.5.1). Koniec przypomnienia, teraz o nowoœciach. 1 W naszym programie widzimy tak w³aœnie zdefiniowane wyra¿enie lambda. Obiekt lambda, w którym bêdziemy je przechowywaæ, nazywamy d³ug¹, ale obrazow¹ nazw¹ czy_mniejsze_int. Patrz¹c na cia³o tego wyra¿enia lambda, ³atwo zauwa¿ysz, ¿e otrzymuje ono dwa argumenty (dwie wartoœci typu int) i sprawdza, czy pierwsza wartoœæ jest mniejsza od drugiej. Jeœli „tak”, to zwraca ono wartoœæ true, jeœli „nie”, wówczas zwraca wartoœæ false. s t a n d a r d u C + + 1 4 2 . C e c h y j ê z y k a w p r o w a d z o n e d o 3 Oto wywo³anie tego wyra¿enia lambda dla dwóch wartoœci typu int: 5 oraz 2. Na ekranie pojawia siê odpowiedŸ false. OdpowiedŸ jest „s³owna” dziêki manipulatorowi boolalpha, którym powiedzie - liœmy strumieniowi cout, ¿e wolimy „s³ownie” 2. A co bêdzie, jeœli to samo wyra¿enie lambda zastosujemy wobec dwóch wartoœci typu double? 4 Oto taka sytuacja. Niestety nie zadzia³a to poprawnie. Skoro wartoœci 5.1 oraz 5.9 (czyli typu double) zosta³y wys³ane wyra¿eniu lambda obs³uguj¹cemu wartoœci typu int, to nast¹pi³o ich obciêcie do typu int. Zatem wyra¿enie lambda porówna³o, czy (5 5). Wartoœci¹ tego wyra¿enia jest false, bo przecie¿ 5 nie jest mniejsze od 5. Wniosek? Nasze wyra¿enie lambda nie nadaje siê do porównywania wartoœci typu double. Nie jest uniwersalne. Ten k³opot rozwi¹zuje mo¿liwoœæ wytworzenia uogólnionego wyra¿enia lambda, na które pozwala nam standard C++14. 5 Oto jego definicja. Zacytujmy: auto czy_mniejsze_uniwersalne = [] (auto m, auto k) { return m k; }; Poleć książkęKup książkę o d e n o z d a w o r p w a k y z ê j y h c e C . 2 4 1 + + C u d r a d n a t s 96 Nowoœci C++14 w wyra¿eniach lambda Jak widaæ, zamiast okreœlaæ typ argumentów m i k, postawiliœmy tam s³owa auto. Dziêki temu stworzyliœmy jakby szablon wyra¿eñ lambda o danej nazwie. Takie uogólnione wyra¿enie lambda mo¿na zastosowaæ do wartoœci ró¿nych innych typów. (Oczywiœcie takich, wobec których operator ma sens). Oto kilka takich sytuacji. 6 U¿ycie wyra¿enia lambda czy_mniejsze_uniwersalne wobec argumentów typu (int, int). Dzia³a, podobnie jak to poprzednie (3). 7 U¿ycie wobec argumentów typu (double, double). Dzia³a poprawnie, czego poprzednia lambda (4) nie potrafi³a. 8 U¿ycie wobec argumentów typu (char, char). Tak¿e dzia³a poprawnie. 9 Dwa argumenty naszego uogólnionego wyra¿enia lambda wcale nie musz¹ byæ tego samego typu. Przecie¿ ka¿dy z nich ma swoje w³asne okreœlenie auto. Oto u¿ycie tego wyra¿enia wobec pary argumentów (int, double). Jak widaæ, tak¿e i ono dzia³a po - prawnie. Ba A oto bardziej karko³omne zastosowanie. Porównanie argumentów (char, int), a potem Bb argumentów (char, double). (Patrz¹c na ekran i sprawdzaj¹c, czy i jak to dzia³a, pamiêtaj ¿e kod ASCII znaku p to 112). @ Pora na podsumowanie: uogólnione wyra¿enie lambda to narzêdzie bardzo wygodne i bardzo proste w u¿yciu. Sprawia, ¿e wyra¿enie lambda, które w³aœnie tworzymy, mo¿e byæ bardziej uniwersalne, bo mo¿na je zastosowaæ do wielu ró¿nych typów argumentów. X Dociekliwym wyjaœniam, ¿e ca³y mechanizm uogólnionego wyra¿enia lambda polega na tym, ¿e kompilator zamienia je nie na obiekt funkcyjny maj¹cy funkcjê sk³adow¹ operator(), ale na obiekt funkcyjny maj¹cy szablon funkcji sk³adowej operator(). W zale¿noœci od tego, jakie podajemy argu men - ty aktualne naszemu wyra¿eniu lambda, kompilator produkuje tak¹ lub inn¹ prze³adowan¹ wersjê tego operatora(). Jak widaæ, ca³y spryt uogólnionego wyra¿enia lambda wynika z tego, ¿e u¿ywa ono szablonu. Szablony zaœ, jak to ju¿ kiedyœ ustaliliœmy, to nie: v run-time polimorfizm, innymi s³owy, wielopostaciowoœæ zrealizowana ju¿ w trakcie pracy programu (za pomoc¹ funkcji wirtualnej), v lecz compile-time polimorfizm inaczej: wielopostaciowoœæ zrealizowana w trakcie kompilacji (za pomoc¹ szablonu). Przyznam siê, ¿e nie lubiê tych uogólnionych wyra¿eñ lambda nazywaæ poli morficz - nymi. Niepotrzebnie kojarzy siê to z funkcjami wirtualnymi, a co tu du¿o mówiæ, ten mechanizm nie dorasta funkcjom wirtualnym do piêt. 2.7.2 Przyk³ad definicji obiektu na liœcie wychwytywania i jego inicjalizacja Jak wiadomo, wyra¿enie lambda mo¿e wychwyciæ jakieœ lokalne obiekty auto ma - tyczne dostêpne w zakresie, w którym ono nast¹pi³o. Dziêki temu mo¿e z nich korzystaæ w swoim ciele. Poleć książkęKup książkę Nowoœci C++14 w wyra¿eniach lambda 97 + C++14 daje nam dodatkow¹ mo¿liwoœæ: Na liœcie wychwytywania mo¿emy zdefiniowaæ jakiœ dodatkowy obiekt, który nam siê przyda w ciele wyra¿enia lambda. Od razu inicjalizujemy go jakimœ wyra¿eniem. Mówi¹c œciœlej – jeœli na liœcie wychwytywania umieœcimy nazwê z inicjalizacj¹: nazwa = wyra¿enie_inicjalizacyjne; to tak, jakbyœmy zdefiniowali zmienn¹ i zainicjalizowali j¹. Jej zakres to zakres cia³a wyra¿enia lambda. Jej typ jest taki, jakby przed jej nazw¹ sta³o s³owo auto (czyli wynika on z typu wyra¿enia inicjalizacyjnego). Co ciekawe i bardzo wygodne – w wyra¿eniu, które inicjalizuje zmienn¹, wolno nam nawet wykorzystaæ nazwy lokalnych (automatycznych) obiektów dostêpnych w za - kre sie, w którym nasze wyra¿enie lambda tworzymy. Jeœli potrafisz sobie wyobraziæ wyra¿enie lambda jako obiekt funkcyjny, to przedstawiony tu mechanizm mo¿esz rozumieæ jako mo¿liwoœæ dodania do wyra¿enia lambda nowych danych sk³adowych. Te i dalsze interesuj¹ce szczegó³y zobaczymy w programie poni¿ej. wIII `$ - re set numerkow #include iostream #include memory using namespace std; //***************************************************************************************************************** int main() { s t a n d a r d u C + + 1 4 2 . C e c h y j ê z y k a w p r o w a d z o n e d o int h = 1; int k = 12; double e = 2.71; // definicja wyra¿enia lambda auto impakt = [obj = 5, h = h + 400, zmienna = k * (k + 1), ref = e] () { // k = 1; b³¹d, bo k nie by³o wychwycone (s³u¿y jednie do inicjalizacji) b³¹d (jak wy¿ej) // e = 1.0; ref = ref + 10; // zmienna++; // ¬ modyfikacja dozwolona tylko wtedy, jeœli lambda... ...ma przydomek mutable cout obj obj , h = h , zmienna = zmienna , ref = ref endl; return; }; impakt(); cout Po wykonaniu lambdy impakt h = h endl; // wykonanie wyra¿enia lambda } 1 2 3 4 5 6 7 8 9 Poleć książkęKup książkę 98 Nowoœci C++14 w wyra¿eniach lambda Tak wygl¹da³ bêdzie ekran po wykonaniu tego programu: obj 5, h = 401, zmienna = 156, ref = 12.71 Po wykonaniu lambdy impakt h = 1 Omówienie 2 W naszym programie definiujemy wyra¿enie lambda. Definiujemy je (dla uprosz - czenia) nie w wywo³aniu jakiejœ funkcji algorytmu, ale – ¿e tak powiem – w postaci „wolno stoj¹cej”. Zostaje ono zapisane w obiekcie lambda o nazwie impakt. Fakt, ¿e tak w³aœnie post¹piliœmy, nie ma nic wspólnego z przedmiotem obecnego paragrafu. Po prostu dziêki temu unikn¹³em koniecznoœci definiowania funkcji -algorytmu. Jak widzisz, lista wychwytywania (czyli to, co jest zamkniête w kwadratowym nawiasie) jest doœæ rozbudowana; jest w niej kilka cz³onów oddzielonych przecinkami: [obj = 5, h = h + 400, zmienna = k * (k + 1), ref = e] Jest ich a¿ tyle, bo chcê pokazaæ ró¿ne warianty nowego typu zapisu wychwytywania z inicjalizacj¹. Nie przera¿aj siê jednak, zwykle zastosujesz tylko jeden, no, mo¿e dwa takie cz³ony. Omówimy je po kolei. o d e n o z d a w o r p w a k y z ê j y h c e C . 2 4 1 + + C u d r a d n a t s cz³on: obj = 5 Taki zapis na liœcie wychwytywania odpowiada jakby zapisowi: auto obj = 5; // pseudokod co oznacza nastêpuj¹ce polecenie dla kompilatora: zdefiniuj w ramach tego wyra¿enia lambda lokaln¹ zmienn¹ o nazwie obj i inicjalizuj j¹ wartoœci¹ wyra¿enia (5). Wyra¿enie to jest (jak wiadomo) typu int, wiêc niech zmienna obj bêdzie w³aœnie takiego typu. cz³on: h = h +400 Taki zapis mówi kompilatorowi, ¿e chcielibyœmy, aby zdefiniowa³ nam on lokalny obiekt o nazwie h i inicjalizowa³ go wyra¿eniem (h + 400). Ale uwaga: to h stoj¹ce na prawo od znaku = (czyli w wyra¿eniu inicjalizacyjnym) to zupe³nie inne h ni¿ to po lewej. Dotyczy ono jakiegoœ h, które istnieje i jest dostêpne w zakresie, w którym akurat nasz¹ lambdê definiujemy. W tym przypadku bêdzie to obiekt 1 o nazwie h, zdefiniowany w zakresie funkcji main. + Zapamiêtaj to. Jeœli w wyra¿eniu wychwytuj¹cym mamy nawet tê sam¹ nazwê po jednej i drugiej stronie znaku = , np.: h = h owo h z lewej oznacza lokalny obiekt, który definiujemy na u¿ytek cia³a wyra¿enia lambda, zaœ to h z prawej jest nazw¹ jakiegoœ obiektu, który powinien byæ dostêpny w zakresie, w którym nasz¹ lambdê definiujemy. Aby unikn¹æ pomy³ek i nieporozumieñ, zwykle dajê tym lokalnym obiektom inne nazwy, ni¿ maj¹ obiekty stoj¹ce po prawej. Przyk³ad tego widzisz na nastêpnej pozycji listy wychwytywania, czyli... cz³on: zmienna = k * (k + 1) Tutaj sprawa jest jasna i czytelna, wiêc nie trzeba tego objaœniaæ. Dodam wiêc tylko, ¿e obiekt o nazwie k zosta³ tu tylko u¿yty w wyra¿eniu inicjalizuj¹cym, ale to wcale nie znaczy, ¿e zosta³ wychwycony. Zreszt¹ zobacz, próba u¿ycia go w ciele wyra¿enia Poleć książkęKup książkę Nowoœci C++14 w wyra¿eniach lambda 99 lambda (3) wywo³a b³¹d kompilatora. (Dlatego tê instrukcjê musia³em opatrzyæ znakami komentarza). cz³on: ref = e 2.7.3 A to jest definicja referencji (przezwiska) o nazwie ref, która od razu dowiaduje siê (dziêki inicjalizacji), ¿e jest przezwiskiem obiektu e. Sam obiekt e nie jest wychwy - cony, wiêc u¿ycie go w ciele (4) by³oby b³êdem. Poniewa¿ jednak wytworzyliœmy w³aœnie referencjê do tego obiektu, to mo¿na z niego korzystaæ za jej pomoc¹ (5). 6 Przypominam, ¿e wprawdzie wyra¿enia lambda pozwalaj¹ nam wychwyciæ jakieœ obiekty przez wartoœæ (czyli przez kopiê), ale kompilator nie pozwoli nam tych kopii modyfikowaæ. Aby to by³o mo¿liwe, powinniœmy nasz¹ lambdê opatrzyæ przy dom - kiem mutable (zob. Opus, §30.3.5). Poniewa¿ akurat tutaj tego nie zrobiliœmy, musia³em instrukcjê 6 uj¹æ w komentarz. 7 Oto jest instrukcja, w której wypisujemy na ekranie wartoœci ró¿nych obiektów dostêpnych nam w ramach cia³a naszego wyra¿enia lambda. Na ekranie mo¿esz zobaczyæ na przyk³ad wartoœæ lokalnego obiektu h (401). 9 Potem, po zakoñczeniu definicji wyra¿enia lambda i po wykonaniu go (8), wypi su - jemy wartoœæ tego h, które by³o zdefiniowane w funkcji main. Jak widaæ, ta wartoœæ nie zosta³a zmieniona i nadal wynosi 1. @ Podsumujmy. C++14 wzbogaci³ mo¿liwoœci listy wychwytywania wyra¿eñ lambda. Mo¿emy tam wytwarzaæ (i inicjalizowaæ) nowe pomocnicze obiekty, z których chcemy skorzystaæ w ciele wyra¿enia lambda. Inicjalizacja tych pomocniczych obiektów mo¿e byæ dowolnym wyra¿eniem – nawet korzystaj¹cym z obiektów dostêpnych w zakresie, w którym nasz¹ lambdê defi niu - jemy. O pewnym szczególnym zastosowaniu takiej inicjalizacji porozmawiamy w na - stêp nym paragrafie. Przyk³ad wychwycenia na zasadzie przeniesienia (move) Jak wiemy, lista wychwytywania pozwala wyra¿eniu lambda uzyskaæ dostêp do obiektów przez wartoœæ, czyli przez kopiê (albo przez sporz¹dzenie referencji do danego obiektu). A co bêdzie, jeœli interesuj¹cego nas obiektu nie da siê kopiowaæ, wolno go tylko przenosiæ? To znaczy, co bêdzie, gdy informacjê zawart¹ w tym obiekcie mo¿na jedynie wyj¹æ z jednego obiektu i w³o¿yæ do drugiego? Nie mo¿e ona byæ obecna w obu obiektach równoczeœnie. Wyra¿enie lambda nie mo¿e takiego obiektu wychwyciæ przez wartoœæ (kopiê). Przyk³adem takich niekopiowalnych obiektów s¹ „sprytne wskaŸniki” realizowane przez biblioteczn¹ klasê std::unique_ptr. (Opus , §27.7.1). Jeœli w programie pos³ugujemy siê nimi, to jak sprawiæ, ¿eby nasze wyra¿enie lambda by³o zdolne wychwyciæ taki wskaŸnik? W C++11 takiego obiektu wychwyciæ siê nie da³o. C++14 ju¿ nam to umo¿liwia. O tym teraz porozmawiamy. Sprawê rozwi¹zuje bardzo prosto poznana w poprzednim paragrafie inicjalizacja na liœcie wychwytywania. Zobaczmy to na przyk³adzie. Bêd¹ w nim dwa wyra¿enia s t a n d a r d u C + + 1 4 2 . C e c h y j ê z y k a w p r o w a d z o n e d o Poleć książkęKup książkę 100 Nowoœci C++14 w wyra¿eniach lambda wIII `$ - re set numerkow lambda. Jedno wychwyci sprytny wskaŸnik do pojedynczego obiektu, a drugie – do tablicy obiektów. #include iostream #include memory using namespace std; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// struct Tklasa { int skladnik = 0; ~Tklasa() { cout Destruktor ~Tklasa endl; } }; //***************************************************************************************************************** int main() { 1 2 cout Definicja sprytnego wskaznika do pojedynczego obiektu\n ; unique_ptr Tklasa spryt { new Tklasa }; o d e n o z d a w o r p w a k y z ê j y h c e C . 2 4 1 + + C u d r a d n a t s { // lokalny zakres w celach szkoleniowych ------------------- auto lambda1 = [sw = std::move(spryt) ] () { sw- skladnik = 4; cout Wykonuje sie lambda1 endl; }; if(!spryt) cout A teraz obiekt spryt NIE ma juz prawa wlasnosci endl; cout Przed wykonaniem lambdy endl; lambda1(); lambda1(); // 1. wykonanie lambdy // 2. wykonanie lambdy cout --- Teraz nastapi koniec zakresu istnienia lambdy1\n ; } // koniec lokalnego zakresu ------------------------- cout --- Skonczyl sie zakres istnienia lambdy1\n ; cout PROBY Z TABLICA endl; // sprytny wskaŸnik do tablicy 5-elementowej (z rezerwacj¹ tej tablicy) constexpr int rozmiar = 5; unique_ptr Tklasa[] wsktab { new Tklasa[rozmiar] }; { // drugi lokalny zakres (w celach szkoleniowych) ============= auto lamTab = [stab = std::move(wsktab), rozmiar] () { for(int i = 0 ; i rozmiar ; ++i){ stab[i].skladnik = i; } cout Pracuje lamTab\n ; 3 4 5 6 7 8 9 Ba Bb Bc Poleć książkęKup książkę Nowoœci C++14 w wyra¿eniach lambda }; cout Przed wywolaniem lamTab\n ; lamTab(); lamTab(); cout === Zakonczyl sie obszar istnienia lamTab endl; 101 Bd Be 9 Bf s t a n d a r d u C + + 1 4 2 . C e c h y j ê z y k a w p r o w a d z o n e d o } // koniec lokalnego zakresu ============================ Bf cout === Koniec funkcji main endl; 7 } Na ekranie pojawi siê tekst: Definicja sprytnego wskaznika do pojedynczego obiektu A teraz obiekt spryt NIE ma juz prawa wlasnosci Przed wykonaniem lambdy Wykonuje sie lambda1 Wykonuje sie lambda1 --- Teraz nastapi koniec zakresu istnienia lambdy1 Destruktor ~Tklasa --- Skonczyl sie zakres istnienia lambdy1 PROBY Z TABLICA Przed wywolaniem lamTab Pracuje lamTab Pracuje lamTab === Zakonczyl sie obszar istnienia lamTab Destruktor ~Tklasa Destruktor ~Tklasa Destruktor ~Tklasa Destruktor ~Tklasa Destruktor ~Tklasa === Koniec funkcji main Omówienie sposobów wy chwyt ywa nia na za sad zie prze nos zenia O bibliotecznej klasie „sprytnych wskaŸników” unique_ptr rozmawialiœmy w Opusie (§27.7.1). S³u¿y ona do tworzenia obiektów zachowuj¹cych siê podobnie jak wskaŸ - niki. W sprytnym wskaŸniku mo¿esz przechowaæ adres jakiegoœ obiektu, który wy - two rzy³eœ w zapasie pamiêci operatorem new. Sprytny wskaŸnik ma tê dodatkow¹ zdol noœæ, ¿e gdy koñczy siê czas jego ¿ycia, to – ¿e tak powiem – „poci¹ga on za sob¹ do grobu” obiekt, którego adres przechowywa³. Jak sprytny wskaŸnik to robi? Po prostu w jego destruktorze u¿yta jest instrukcja delete kasuj¹ca obiekt, którym siê do tej pory opiekowa³. Jak wiemy, mo¿e istnieæ wiele wskaŸników wskazuj¹cych na ten sam obiekt. W przy - padku sprytnych wskaŸników mog³oby to byæ groŸne. WyobraŸ sobie, ¿e na jeden obiekt stworzony w zapasie pamiêci operatorem new wskazuje kilka sprytnych wskaŸ - ników. Gdy jednemu z tych sprytnych wskaŸników skoñczy siê czas ¿ycia, jego destruktor zlikwiduje cenny obiekt w zapasie pamiêci. Jeœli pozosta³e wskaŸniki nadal bêd¹ chcia³y z tym „cennym” obiektem pracowaæ – wywo³a to katastrofê. Aby tej katastrofy unikn¹æ, sprytne wskaŸniki unique_ptr stosuj¹ zasadê, ¿e tylko jeden z nich mo¿e w danej chwili znaæ adres naszego obiektu z zapasu pamiêci. Jeœli zrobimy przy pisanie takiego wskaŸnika do jakiegoœ innego: spryciarz_nowy = spryciarz_stary; Poleć książkęKup książkę o d e n o z d a w o r p w a k y z ê j y h c e C . 2 4 1 + + C u d r a d n a t s 102 Nowoœci C++14 w wyra¿eniach lambda odbêdzie siê to nie na zasadzie skopiowania cennego adresu, ale na zasadzie przenie - sie nia go. Innymi s³owy, spryciarz_stary przeka¿e cenny adres sprycia rzo wi_no we mu, a sam o tym adresie zapomni. Niby to genialne, ale w przypadku, gdybyœmy chcieli pracowaæ z takim obiektem w ramach wyra¿enia lambda, to jak zorganizowaæ jego wychwycenie? Przecie¿ nie mo¿na tego zrobiæ na zasadzie wychwycenia przez wartoœæ (czyli przez kopiê). Zatem jak taki sprytny wskaŸnik mo¿e zostaæ wychwycony przez wyra¿enie lambda? Jak wychwyciæ: „sprytny wskaŸnik opiekuj¹cy siê pojedynczym obiektem” 3 unique_ptr Tklasa spryt { new Tklasa }; To jest definicja sprytnego wskaŸnika o nazwie spryt. Jest on typu unique_ptr Tklasa , czyli mo¿e siê on opiekowaæ adresem obiektu typu Tklasa. (To taka pomocnicza klasa zdefi nio wana na górze programu 1). W nawiasie klamrowym widzimy, ¿e nasz sprytny wskaŸnik jest od razu inicjalizowany. Czym? Adresem obiektu typu Tklasa, który wytwarzamy operatorem new w zapasie pamiêci. 4 i 9 W celach szkoleniowych definiujemy sobie w programie pewien lokalny zakres. Oczywiœcie w Twoim programie nie musisz tego robiæ. Mnie jest on potrzebny, by pokazaæ Ci, kiedy dok³adnie nast¹pi „poci¹gniêcie do grobu”. 5 Oto definicja prostego wyra¿enia lambda. Jego cia³o jest rozpisane na kilka linijek. Dla uproszczenia naszej rozmowy ta definicja nie jest zapakowana do wywo - ³a nia jakiejœ funkcji-algorytmu, ale jest umieszczona w obiekcie lambda o na - zwie lambda1. (Podobnie robiliœmy w poprzednich przyk³adach, aby sobie dodatkowo nie za prz¹ taæ g³owy algorytmami). + Zwróæ uwagê na listê wychwytywania. Tu jest kwintesencja tego programu. auto lambda1 = [sw = std::move(spryt) ] () // itd. Definiu jemy tutaj jakiœ obiekt o nazwie sw i inicjalizujemy go wartoœci¹ wyra¿enia move(spryt). Innymi s³owy, sprawiamy tutaj, ¿e adres przechowywany w obiekcie spryt zostaje przeniesiony do obiektu sw. O funkcji move rozmawialiœmy w Opusie w §22.10. Pytanko: jakiego typu jest obiekt sw? OdpowiedŸ: takiego, jakby przed nim sta³o s³owo zastêpcze auto. auto sw = std::move(spryt); // czyli typu: unique_ptr Tklasa W ten sposób sprawiliœmy, ¿e od tej pory obiektem wytworzonym ope ra to - rem new (w instrukcji 3) opiekuje siê wy³¹cznie sprytny wskaŸnik sw. W ciele wyra¿enia lambda1 stawiamy jakieœ przyk³adowe instrukcje korzystaj¹ce z obiektu wskazywanego przez sw, nastêpnie stawiamy klamrê } koñcz¹c¹ definicjê tego cia³a. Potem 6 nastêpuje œrednik, bo to przecie¿ koniec d³ugiej instrukcji, która rozpoczê³a siê w 5. Ta d³uga instrukcja: 1) zdefiniowa³a wyra¿enie lambda i... 2) zapamiêta³a je w obiekcie lambda o nazwie lambda1. 7 Jesteœmy znowu w zakresie funkcji main. Dla ciekawoœci sprawdzamy teraz sprytny wskaŸnik o nazwie spryt. Jeœli teraz znajduje siê w nim ju¿ nullptr, to znaczy, ¿e naprawdê odda³ on swój cenny skarb sprytnemu wskaŸnikowi sw. Na ekranie widzimy 7, ¿e tak rzeczy wiœ cie siê sta³o. Poleć książkęKup książkę Nowoœci C++14 w wyra¿eniach lambda 103 8 Oto uruchomienie naszego wyra¿enia lambda. Robiê to dwukrotnie, abyœ zobaczy³, ¿e sprytny wskaŸnik sw istnieje ca³y czas, dopóki istnieje obiekt lambda1. Nie znika wiêc po wykonaniu funkcji lambda. Przecie¿ ktoœ móg³by wywo³aæ lambda1 po raz kolejny. 9 Nadchodzi koniec naszego „szkoleniowego” lokalnego zakresu, w którym zdefinio wa - liœmy nasz obiekt lambda1. Tutaj wiêc obiekt lambda1 przestaje istnieæ. Skoro tak, to przestanie równie¿ istnieæ jego (lokalny) sprytny wskaŸnik sw. W chwili swojej „œmierci” ten¿e biblioteczny sprytny wskaŸnik sw wywo³uje swój destruktor, w którym (uwierz mi na s³owo) wykonywana jest instrukcja delete kasuj¹ca nasz obiekt Tklasa z zapasu pamiêci. To w³aœnie moment „poci¹gniêcia do grobu”. Czy to dzia³a? Dzia³a, potwierdza to gadaj¹cy destruktor 2, którego wypis pojawia siê na ekranie 9. Jak wychwyciæ: „sprytny wskaŸnik opiekuj¹cy siê tablic¹ obiektów”? Poniewa¿ w zapasie pamiêci najczêœciej rezerwuje siê nie tyle pojedyncze obiekty, co tablice takich obiektów, zobaczmy i tak¹ sytuacjê. Ba Oto definicja sprytnego wskaŸnika mog¹cego wskazywaæ na tablicê obiektów typu Tklasa. unique_ptr Tklasa[] wsktab { new Tklasa[rozmiar] }; Jest on typu unique_ptr Tklasa[ ] . Ten nawias kwadratowy sprawia, ¿e sprytny wskaŸnik dowiaduje siê, ¿e to, czym bêdzie siê opiekowaæ, jest tablic¹, zatem w razie likwidacji ma pos³u¿yæ siê operatorem delete [ ] (a nie prostym delete). Definiowany tutaj sprytny wskaŸnik (o nazwie wsktab) jest od razu inicjalizowany. Co robi ta inicjalizacja? Wytwarza w zapasie pamiêci (operatorem new[ ]) piêcio elemen - tow¹ tablicê obiektów typu Tklasa i jej adres przekazuje sprytnemu wskaŸ ni kowi. Od tej pory wsktab wie, któr¹ tablic¹ ma siê opiekowaæ. Bb Znowu w celach wy³¹cznie ilustracyjnych definiujemy lokalny zakres. Oczywiœcie w swoim programie nie musisz tego robiæ. s t a n d a r d u C + + 1 4 2 . C e c h y j ê z y k a w p r o w a d z o n e d o Bc To jest definicja drugiego wyra¿enia lambda w naszym przyk³adzie. Jej cia³o jest rozpisane na kilka linijek. Po nim nastêpuje œrednik Bd koñcz¹cy tê d³ug¹ instrukcjê definicji Bc. Jak widzisz, to wyra¿enie lambda inicjalizuje obiekt lambda o nazwie lamTab. Dla nas najwa¿niejsza jest tutaj lista wychwytywania. Oto jej pierwszy cz³on: stab = std::move(wsktab) // czyli jakby: auto stab = std::move(wsktab) Jest to definicja lokalnego (dla lambdy) obiektu o nazwie stab. Jakiego jest on typu? Takiego jak inicjalizuj¹ce go wyra¿enie. Wyra¿eniem inicjalizuj¹cym jest wywo³anie bibliotecznej funkcji move. Sprawia ona, ¿e cenny adres, przechowywany w sprytnym wskaŸniku wsktab, zostanie stamt¹d wyjêty i w³o¿ony do sprytnego wskaŸnika stab. (Od tej pory to wskaŸnik stab odpowiada za ewentualne „poci¹gniêcie do grobu” tablicy, natomiast wsktab zostaje z tego obowi¹zku zwolniony). Aby móc w wyra¿eniu lambda pracowaæ z t¹ tablic¹, powinniœmy znaæ jej rozmiar. Za³atwia to drugi cz³on listy wychwytywania (Bc). Jak widaæ, ten rozmiar wy chwy tu - jemy po prostu przez wartoœæ. Be Oto dwukrotne wywo³anie funkcji lambda lamTab. Robiê to dwukrotnie, abyœ nie pomyœla³, ¿e to zakoñczenie wykonywania lamTab spowoduje likwidacjê tablicy. Nie! Przecie¿ tablica mo¿e byæ potrzebna w sytuacji, gdybyœmy nasze wyra¿enie lambda chcieli wywo³aæ po raz trzeci. Poleć książkęKup książkę 104 C++14 a funkcje constexpr Likwidacja tablicy nast¹pi dopiero wtedy, gdy bêdzie „gin¹³” sam obiekt lambda lamTab. A kiedy siê to stanie? Ju¿ za chwilê. To w³aœnie w tym celu w programie utworzy³em lokalny zakres BbÖBf. Bf Poniewa¿ obiekt lambda lamTab jest zdefiniowany w lokalnym zakresie, wiêc teraz, gdy ten zakres siê koñczy, obiekt lambda zostaje zlikwidowany. Na ekranie mo¿emy zobaczyæ teksty potwierdzaj¹ce, ¿e sprytny wskaŸnik (bêd¹cy czêœci¹ wyra¿enia lambda) na chwilê przed sw¹ „œmierci¹” wywo³a³ operator delete[ ] likwiduj¹cy tablicê. Dowia du jemy siê o tym znowu dziêki gadaj¹cemu destruktorowi elementów tablicy. To on wypisa³ na ekranie stosowne informacje Bf. Podsumujmy W tym paragrafie dowiedzieliœmy siê, ¿e wprowadzenie w C++14 nowoœci, jak¹ jest mo¿liwoœæ definiowania na liœcie wychwytywania nowych lokalnych obiektów (wraz z ich inicjalizacj¹), otworzy³o dodatkowe drzwi. Mo¿na teraz wychwytywaæ obiekty na zasadzie ich przenoszenia (a nie tylko na zasadzie kopiowania). Zwykle wystarcza nam kopiowanie. Bywaj¹ jednak obiekty, których informacji nie mo¿na kopiowaæ; mo¿na j¹ tylko przenosiæ. Takie s¹ na przyk³ad sprytne wskaŸniki unique_ptr. Tutaj zobaczyliœmy, jak praktycznie zrealizowaæ takie wychwytywanie metod¹ przenoszenia. @ o d e n o z d a w o r p w a k y z ê j y h c e C . 2 4 1 + + C u d r a d n a t s C++11 Poleć książkęKup książkę Skorowidz 265 ! __PRETTY_FUNC TION__ 8 __has_in clude 201-202 A agregat align_val_t 136 alignas › mo¿e byæ klas¹ pochodn¹ (C++17) 247-249 › a ope ra tory new i de lete 134-143 › w prze³adowanych new i de lete dla klasy 141 aligned_alloc (std::) - funkcja bibliot. 140, 144 apostrof › jako sep a ra tor cyfr 44 argu men t › funkcji • dep re cated 114 ar ray - klasa (std::) 184 atrybut 111-118 › car ries_de pend ency 111 › dep re cated 112 › fallthrough 203-212 › maybe_un used 203-212 › nodiscard 203-212 › noreturn 111 auto › rozpoznaje typ rezultatu funkcji 50-51 › rozpoznawanie w inicjalizacji klamrowej 245-246 › w argumencie wyra¿enia lambda 96 › w dekla ra cji tem plate auto 161-165 B biblioteka › szablonów 4 binarny zapis sta³ych dos³ownych 43 bitset (std::) - klasa biblioteczna 46, 217 byte (std::) - klasa biblioteczna 223 byte (std::) - klasa biblioteczna 213-221 Skorowidz C C++14 - nowe cechy jêzyka 43-122 C++17 - nowe cechy jêzyka 123-263 car ries_de pend ency - atrybut 111 class › dep re cated 116 constexpr › a sza b lo n zmiennej 61 › funkcja sk³adowa w C++14 110 › funkcja w C++11 104 › funkcja w C++14 104-110 D dana sk³adowa › dep re cated 114 decltype › u¿yte w parametrze szablonu 161 decltype(auto) › dekla ra cja typu rezultatu 52-58 › nie u¿ywaæ w alternatywnej dekla ra cji funkcji 55 › w sza b lonie funkcji 55 declval (std::) 197 defaultfloat ma nip u la tor 150 dekla ra cja › dostêpu 28 › dowi¹zañ • funkcja get 193, 195 • klasa std::tuple_ele men t 193, 196 • przystosowanie klasy cudzej 198 • przystosowanie klasy swojej 192 • std::tuple_size 193, 196 de lete › a alignas 134-143 › globalny, prze³adowanie 86-93 • a alignas 135 › z alignas dep re cated • prze³adowanie w klasie 141 › argu men t funkcji 114 › atrybut 112 › class, enum 116 Poleć książkęKup książkę 266 Skorowidz › funkcja 113 › funkcja sk³adowa i dana sk³adowa 114 › obie k t 115 › specjalizacji szablonu 118 › typedef, us ing 118 › z zbiorcza defi ni cja zmiennych 116 dostêp dostêpu › wybiórczo 28 › dekla ra cja 28 dowi¹zanie strukturalne 182-200 › a const i vol a tile 183 › do elementów klasy std::ar ray 184 › do obiektów klas i struktur 185 › gdzie stosowaæ 191 › jako re fe ren cja l-wartoœci lub r-wartoœci 190 › jako referencji do l-wartoœci 183 › jako referencji do r-wartoœci 183 dwójkowe liczby wczytane strumieniem 48 dwójkowy zapis › a klasa bitset 46 › sta³ych dos³ownych 43 E enum › dep re cated 116 F fallthrough - atrybut 208 false_type (std::) › pomocniczy typ biblioteczny 80 › fun. bibl. do zwalniania pamiêci 87 free() funkcja › a noexcept 123-127 › auto rozpoznanie typu rezultatu 50-51 › constexpr • w C++11 104 • w C++14 104-110 › constexpr w C++14 104 › decltype(auto) jako typ rezultatu 52-58 › dep re cated 113 › sk³adowa • constexpr w C++14 110 • derpecated 114 › specyfikacja wyj¹tków 123-127 H harmonijka 152-160 › sk³adana w lewo 154 › sk³adana w prawo 154 › z wyra¿eniem pocz¹tkowym 155 has_in clude (__has_in clude) 201-202 hexfloat, ma nip u la tor 149 I if - instrukcja steruj¹ca › z wyra¿eniem inicjalizuj¹cym 179-181 if constexpr 16, 173-178 › w sza b lonie 16 ini cja li za cja › agregatowa 247 › bezpoœrednia 245 • zmiana w standardzie C++17 246 › kopiuj¹ca 245 › w instrukcjach if oraz switch 179-181 › zbiorcza 247 • auto rozpoznawanie jego typu 245-246 inicjalizator › klamrowy is_const 174 is_in te gral 174 is_pointer 174 is_un signed 174 kompilacja warunkowa › a instrukcja if constexpr 173-178 kontekst konwersja › rozwniêcia pakietu 31-33 › wyra¿enia harmonijkowego 157, 159 › chwilowo materializuj¹ca 134 K L lambda (wyra¿enie) › uogólnione 94 › wychwycenie obiektu na zasadzie przeniesienia (move) 99 lista wychwytywania › na niej definicje obiektów lokalnych 96 gl-wartoœæ 134 G M makrodefinicja › __PRETTY_FUNC TION__ 8 malloc (std::) 87 Poleć książkęKup książkę Skorowidz 267 ma nip u la tor › hexfloat 149 maybe_un used - atrybut 205 move 102 N new › a alignas 134-143 › globalny, prze³adowanie 86-93 • a alignas 135 › z alignas • prze³adowanie w klasie 141 niby-rekurencja 14 nodiscard - atrybut 210 noexcept › w typie funkcji 123-127 noreturn - atrybut 111 nothrow_t 136 parametr › szablonu okreœlaj¹cy inny sza b lo n 229-232 podwalina typu wyliczeniowego 214 pomijanie kopiowania 128-133 porz¹dek obliczania sk³adników wyra¿eñ 144-145 post fix wyra¿enia 145 pr-wartoœæ 134 PRETTY_FUNC TION 8 printf 87 przecinek (ope ra to r) › a rozwiniêcie pakietu 35 przestrzeñ nazw › a zagnie¿d¿enie • nowy zapis w C++17 225-228 prze³adowanie › globalnych new, de lete 86-93 › ope ra tora • de lete globalnego w C++14 86-93 puts 87 O R rekurencja 11, 14, 52 › niby-rekurencja 14 rozwiniêcie pakietu › argumentów 7 › dwukrotne 33 › gdzie mo¿e wyst¹piæ? 39 › na liœcie inicjalizacyjnej konstruktora 23 › na liœcie parametrów aktualnych innego szablonu 36-38 › na liœcie pochodzenia klasy 22 › równowa¿ne 33 › typów w { } 34-35 › w dekla ra cji us ing 239-244 › z kontekstem 31-33 › zapêtlone 33 rozwiniêta postaæ › argumentów szablonu 10 › pakietu 13, 152 S sepa ra tory cyfr w sta³ych dos³ownych 44-49, 148 silnia 107 sizeof... 8 specjalizacja › dep re cated 118 › szablonu o zmiennej liczbie parmetrów 23 › szablonu zmiennej 63 specyfikacja wyj¹tków › w C++17 123-127 sprytny wskaŸnik › unique_ptr 99 obie k t › dep re cated 115 ope ra to r › decltype › de lete › sizeof... 8 • u¿yty w parametrze szablonu 161 • globalny, prze³adowanie w C++14 86-93 P pakiet argumentów sz. funkcji 6 › a wskaŸniki z przydomkami const 31 › a wyra¿enia harmonijkowe 152-160 › jak dobraæ siê do argumentów 11-17 › odbierane arg. przez wart., ref., adres 30 › rozwniêta postaæ 7, 152 › z referencjami l-wartoœci 30 › z referencjami obiektów sta³ych 31 › z referencjami r-wartoœci 30 › ze wskaznikami 31 pakiet argumentów szablonu › rozwiniêcie z kontekstem 31-33 pakiet parametrów szablonu 6 › bêd¹cych nazwami innych szablonów 24 › bêd¹cych typami 24 › bêd¹cych wartoœciami 24-25 › trzy rodzaje 24-29 pakietu rozwiniêcie › gdzie mo¿e wyst¹piæ 39 › w nazwie innego szablonu 36-38 › z ope ra torem przecinek 36 Poleć książkęKup książkę 268 Skorowidz › modyfikacja w C++17 224 static_as sert sta³a › dos³owna • z separatorami cyfr 44-49 • zapisana dwójkowo 43 › znakowa typu u8 146 std::ar ray 184 std::false_type - pomocniczy typ 80 std::strtod 151 std::true_type - pomocniczy typ 80 std::unique_ptr 99 stdio 87 strtod - funkcja biblioteczna 151 strumienie a sepa ra tory cyfr 45 switch › z wyra¿eniem inicjalizuj¹cym 179-181 sza b lo n defi ni cji zmiennej 59-85 sza b lo n funkcji › dep re cated 119 › zmienna liczba parametrów 4-10 sza b lo n klas › dep re cated 118 › o zmiennej liczbie parametrów 18-23 sza b lo n zmiennej 59-85 › a constexpr i const 61 › przyk³ad zastosowania 72 › specjalizacja 63 sza b lony szesnastkowy › o zmiennej liczbie parametrów 3-42 › zapis liczb zmiennoprzecinkowych 147-151 • wypisyw. i wczyt. ich strumieniami 149 T Taylora wzór 108 tem plate auto 161-165 to_in te ger (std::) - funkcja biblioteczna 214, 217 to_ulong (std::) - funkcja biblioteczna 50 true_type (std::) › pomocniczy typ biblioteczny 80 trygonometryczne tablice 109 tuple_ele men t (std::) 193, 196 tuple_size (std::) 193, 196 typ › dep re cated 116 › wyliczeniowy enum • jego ini cja li za cja liczb¹ 223 typedef › dep re cated 118 typename 229-232 U uncaught_ex cep tion (std::) zmiana typu rezultatu (C++17) 250-253 uogólnione › wyra¿enie lambda 94 us ing › dekla ra cja › dep re cated 118 • z rozwiniêciem pakietu klas podst. 239-244 valgrind - pro gram diagnostyczny 86 V W wielodziedziczenie 239 wielokropek › w dekla ra cji argumentów fun. 6 › w ostrym nawiasie 6 › w wyra¿eniu rozwijaj¹cym 32 wybiórcze udostêpnianie 28 wychwycenie obiektu na zasadzie przeniesienia (move) 99 wyra¿enia › koñcówkowe 145 › post fix 145 › z³o¿one • porz¹dek ich obliczania 144-145 wyra¿enia harmonijkowe 152-160 • w instrukcjach if oraz switch 179-181 › cztery formy 157 › tzw. kontekst 159 wyra¿enie › incjalizuj¹ce › lambda • uogólnione 94 x-wartoœæ 134 X Z zagnie¿d¿ona zakresowe for › przestrzeñ nazw - nowy zapis C++17 225-228 › a funkcje be gin, end - wg zasad C++17 233-238 › jak w C++11, adaptowaæ klasê 233 › jak w C++17, adaptowaæ klasê 234 zapis dwójkowy › sta³ych dos³ownych 43 znakowa sta³a u8 146 Poleć książkęKup książkę
Pobierz darmowy fragment (pdf)

Gdzie kupić całą publikację:

Opus magnum C++. Misja w nadprzestrzeń C++14/17. Tom 4
Autor:

Opinie na temat publikacji:


Inne popularne pozycje z tej kategorii:


Czytaj również:


Prowadzisz stronę lub blog? Wstaw link do fragmentu tej książki i współpracuj z Cyfroteką: