Nogle fantastiske moderne C ++ - funktioner, som enhver udvikler bør kende

Som sprog har C ++ udviklet sig meget.

Selvfølgelig skete dette ikke natten over. Der var en tid, hvor C ++ manglede dynamik. Det var svært at være glad for sproget.

Men tingene ændrede sig, da C ++ - standardudvalget besluttede at dreje hjulet op.

Siden 2011 har C ++ vist sig som et dynamisk og stadigt udviklende sprog, som mange mennesker har håbet på.

Forstå ikke den forkerte idé om, at sproget er blevet lettere. Det er stadig et af de sværeste programmeringssprog, hvis ikke det sværeste, der bruges bredt. Men C ++ er også blevet meget mere brugervenlig end sine tidligere versioner.

I mit sidste indlæg talte jeg om C ++ - algoritmebiblioteket, der er blevet beriget i løbet af de sidste par år.

I dag skal vi se på nogle nye funktioner (startende fra C ++ 11, som forresten allerede er 8 år gamle), som enhver udvikler gerne vil vide.

Bemærk også, at jeg har sprunget over nogle avancerede funktioner i denne artikel, men jeg er villig til at skrive om dem i fremtiden. ? ️

Gå!

Det automatiske nøgleord

Da C ++ 11 først blev introduceret auto, blev livet lettere.

Ideen med autovar at få C ++ - kompilatoren til at udlede typen af ​​dine data under kompilering - i stedet for at få dig til at erklære typen hver eneste freaking-time. Det var så praktisk, når du har datatyper som nt, int >>>?map

Se på linjenummer 5. Du kan ikke erklære noget uden en initializer. Det giver faktisk mening. Linje 5 lader ikke compileren vide, hvad datatypen kan være.

Oprindeligt autovar noget begrænset. Så i de senere versioner af sproget blev der tilføjet mere magt til det!

I linje 7 og 8 brugte jeg initialisering i parentes. Dette var også en ny funktion tilføjet i C ++ 11.

Husk, at i tilfælde af brug autoskal der være en måde for compileren at udlede din type.

Nu et meget rart spørgsmål, hvad sker der, hvis vi skriverauto a = {1, 2, 3} ? Er det en kompileringsfejl? Er det en vektor?

Faktisk introducerede C ++ 11 pe>. Afstivet initialiseret liste vil blive betragtet som denne lette beholder, hvis dec d auto.std::initializer_list lare

Endelig, som jeg tidligere har nævnt, kan typeafledning af compiler være virkelig nyttig, når du har komplekse datastrukturer:

Glem ikke at tjekke linje 25! Udtrykket auto [v1,v2] = itr.seconder bogstaveligt talt en ny funktion i C ++ 17. Dette kaldes struktureret binding . I tidligere versioner af sproget skulle du udtrække hver variabel separat. Men struktureret binding har gjort det meget mere praktisk.

Desuden, hvis du ønskede at få dataene ved hjælp af reference, tilføjede du bare et symbol - auto &[v1,v2] = itr.second.

Pænt.

Lambda-udtrykket

C ++ 11 introducerede lambda-udtryk, noget som anonyme funktioner i JavaScript. De er funktionsobjekter uden navne, og de fanger variabler i forskellige omfang baseret på en kortfattet syntaks. De kan også tildeles variabler.

Lambdas er meget nyttige, hvis du har brug for en lille hurtig ting, der skal gøres inde i din kode, men du er ikke villig til at skrive en helt separat funktion til det. En anden ret almindelig anvendelse er at bruge dem som sammenligningsfunktioner.

Ovenstående eksempel har meget at sige.

For det første skal du bemærke, hvordan krøllet afstivning initialisering løfter vægten for dig. Derefter kommer generisk begin(), end(), der også er en tilføjelse i C ++ 11. Derefter kommer lambda-funktionen som en komparator for dine data. Parametrene for lambda-funktionen erklæresautosom blev tilføjet i C ++ 14. Før det kunne vi ikke bruge autotil funktionsparametre.

Bemærk hvordan vi starter lambda-udtrykket med en firkantet parentes []. De definerer omfanget af lambda - hvor meget autoritet det har over de lokale variabler og objekter.

Som defineret i dette fantastiske lager på moderne C ++:

  • [] - fanger intet. Så du kan ikke bruge nogen lokal variabel i det ydre omfang inde i dit lambda-udtryk. Du kan kun bruge parametrene.
  • [=]- indfanger lokale objekter (lokale variabler, parametre) i omfang efter værdi. Du kan bruge dem, men kan ikke ændre dem.
  • [&] - fange lokale objekter (lokale variabler, parametre) i omfanget ved henvisning. Du kan ændre dem. Ligesom følgende eksempel.
  • [this]- fang thismarkøren efter værdi.
  • [a, &b]- fange objekter aefter værdi, bved reference.

Så hvis du inden for din lambda-funktion vil transformere dine data til et andet format, kan du bruge lambda ved at drage fordel af scoping. For eksempel:

I ovenstående eksempel, hvis du havde fanget lokale variabler efter værdi ( [factor]) i dit lambda-udtryk, kunne du ikke ændre factori linje 5. Fordi du simpelthen ikke har ret til at gøre det. Misbrug ikke dine rettigheder! ?

Endelig bemærk, at vi tager valsom reference. Dette sikrer, at enhver ændring inde i lambda-funktionen faktisk ændrer vector.

Indledende udsagn indeni hvis & switch

Jeg kunne virkelig godt lide denne funktion af C ++ 17 umiddelbart efter jeg fik at vide det.

Så tilsyneladende kan du nu foretage initialisering af variabler og kontrollere tilstand på det - samtidigt inde i if/switchblokken. Dette er virkelig nyttigt at holde din kode kortfattet og ren. Den generelle form er:

if( init-statement(x); condition(x)) { // do some stuff here } else { // else has the scope of x // do some other stuff }

Gør det i kompileringstid ved constexpr

constexpr er cool!

Sig, at du har noget udtryk at evaluere, og dets værdi ændres ikke, når den er initialiseret. Du kan forudberegne værdien og derefter bruge den som en makro. Eller som C ++ 11 tilbydes, kan du bruge constexpr.

Programmører har tendens til at reducere runtime for deres programmer så meget som muligt. Så hvis der er nogle operationer, kan du få kompilatoren til at tage belastningen fra runtime, så kan runtime forbedres.

Ovenstående kode er et meget almindeligt eksempel på constexpr.

Da vi erklærede Fibonacci-beregningsfunktionen som constexpr, kan kompilatoren forberegnefib(20)i kompileringstid. Så efter kompilering kan den erstatte linjen

const long long bigval = fib(20);med

const long long bigval = 2432902008176640000;

Bemærk, at det godkendte argument er en constværdi. Dette er et vigtigt punkt i deklarerede funktioner constexpr- de argumenter, der sendes, skal også være constexpreller const. Ellers opfører funktionen sig som en normal funktion, hvilket betyder ingen forberegning under kompileringstiden.

Variabler kan også være constexpr. I dette tilfælde, som du kan gætte, skal disse variabler kunne vurderes i kompileringstid. Ellers får du en kompileringsfejl.

Interessant senere i C ++ 17 constexpr-ifogconstexpr-lambdablev introduceret.

Tuples

Meget gerne pair, tupleer en samling af faste størrelse værdier af forskellige datatyper.

Nogle gange er det mere praktisk at bruge i std::arraystedet for tuple. arraysvarer til almindelig C-type array sammen med et par funktioner i C ++ standardbiblioteket. Denne datastruktur blev tilføjet i C ++ 11.

Fradrag for argument for klasseskabelon

Et meget detaljeret navn for en funktion. Ideen er, at fra C ++ 17 vil argumentfradrag for skabeloner også ske for standard klasseskabeloner. Tidligere blev det kun understøttet til funktionsskabeloner.

Som resultat,

std::pair user = {"M", 25}; // previous std::pair user = {"M", 25}; // C++17

Fradragstypen sker implicit. Dette bliver endnu mere bekvemt for tuple.

// previous std::tuple user ("M", "Chy", 25); // deduction in action! std::tuple user2("M", "Chy", 25);

Denne funktion ovenfor giver ikke mening, hvis du ikke er fortrolig med C ++ - skabeloner.

Smarte henvisninger

Markører kan være helvede.

På grund af den frihed, som sprog som C ++ giver programmører, bliver det nogle gange meget let at skyde sig selv i foden. Og i mange tilfælde er henvisere ansvarlige for skaden.

Heldigvis introducerede C ++ 11 smarte pointer, pointer, der er langt mere bekvemme end rå pointer. De hjælper programmører med at forhindre hukommelseslækage ved at frigøre det, når det er muligt. De giver også undtagelsessikkerhed.

Jeg tænkte på at skrive om de smarte pointer i C ++ i dette indlæg. Men tilsyneladende er der mange vigtige detaljer om dem. De fortjener deres eget indlæg, og jeg er bestemt villig til at skrive en om dem i nær fremtid.

Det er alt for i dag. Husk, at C ++ faktisk tilføjede mange flere nyere funktioner i de nyeste versioner af sproget. Du bør tjekke dem ud, hvis du føler dig interesseret. Her er et fantastisk lager på moderne C ++, der bogstaveligt talt hedder Awesome Modern C ++!

Adios!