Néhány félelmetes modern C ++ funkció, amelyet minden fejlesztőnek ismernie kell

Nyelvként a C ++ sokat fejlődött.

Természetesen ez nem egyik napról a másikra történt. Volt idő, amikor a C ++ - ból hiányzott a dinamizmus. Nehéz volt szeretni a nyelvet.

De a helyzet megváltozott, amikor a C ++ szabványbizottság úgy döntött, hogy felpörgeti a kormányt.

2011 óta a C ++ dinamikus és folyamatosan fejlődő nyelvként jelent meg, amelyet sokan reméltek.

Ne értse azt a rossz elképzelést, hogy a nyelv könnyebbé vált. Még mindig az egyik legnehezebb programozási nyelv, ha nem a legnehezebb, amelyet széles körben használnak. De a C ++ is sokkal felhasználóbarátabb lett, mint a korábbi verziói.

Legutóbbi bejegyzésemben a C ++ algoritmus könyvtárról beszéltem, amely az elmúlt néhány évben gazdagodott.

Ma megvizsgálunk néhány új funkciót (a C ++ 11-től kezdődően, amely egyébként már 8 éves), amelyeket minden fejlesztő szeretne tudni.

Vegye figyelembe azt is, hogy kihagytam néhány speciális funkciót ebben a cikkben, de hajlandó vagyok írni a jövőben ezekről. ? ️

Megy!

Az automatikus kulcsszó

A C ++ 11 első bevezetésekor az autoélet könnyebbé vált.

Az autovolt az elképzelés , hogy a C ++ fordító fordítsa le az adatok típusát a fordítás során - ahelyett, hogy a típust minden időkben deklarálná . Ez olyan kényelmes volt, ha olyan adattípusok vannak, mint például az nt, int >>>?map

Nézze meg az 5-ös sort initializer. Anélkül nem jelenthet be valamit . Ennek valójában van értelme. Az 5. sor nem közli a fordítóval, hogy mi lehet az adattípus.

Kezdetben autonémileg korlátozott volt. Aztán a nyelv későbbi verzióiban nagyobb erővel bővült!

A 7. és 8. sorban zárójeles inicializálást használtam. Ez a C ++ 11 új funkciója is volt.

Ne feledje, hogy használat esetén autoa fordítónak valamilyen módon le kell vezetnie a típusát.

Most egy nagyon szép kérdés, mi történik, ha írunkauto a = {1, 2, 3} ? Ez fordítási hiba? Ez egy vektor?

Valójában a C ++ 11 bevezette a pe> -t. A merevített inicializált lista ennek a könnyű konténernek tekinthető, ha dec d automatikus.std::initializer_list lare

Végül, amint azt korábban említettem, a fordító által történő levezetés valóban hasznos lehet, ha összetett adatstruktúrái vannak:

Ne felejtsd el megnézni a 25. sort! A kifejezés auto [v1,v2] = itr.secondszó szerint új funkció a C ++ 17-ben. Ezt strukturált kötésnek nevezzük . A nyelv korábbi verzióiban minden változót külön kellett kibontania. De a strukturált kötés sokkal kényelmesebbé tette.

Sőt, ha referenciával szeretné megszerezni az adatokat, csak hozzá kell tennie egy szimbólumot - auto &[v1,v2] = itr.second.

Tiszta.

A lambda kifejezés

A C ++ 11 lambda kifejezéseket vezetett be, valami hasonló névtelen funkciókat a JavaScript-ben. Ezek függvényobjektumok, nevek nélkül, és változókat különféle hatókörökön rögzítenek, tömör szintaxis alapján. Változókhoz is rendelhetők.

A lambdák nagyon hasznosak, ha szüksége van néhány apróságra, amit a kódban kell elvégeznie, de nem hajlandó ehhez egész külön függvényt írni. Egy másik meglehetősen gyakori használat, ha összehasonlító függvényként használják őket.

A fenti példa sokat mond.

Először is vegye figyelembe, hogy a göndör merevítésű inicializálás hogyan emeli meg a súlyt az Ön számára. Ezután jön egy általános begin(), end(), amely szintén kiegészítés a C ++ 11-ben. Ezután jön a lambda függvény összehasonlító elemként az adatokhoz. A lambda függvény paramétereit deklaráljukautoamelyet C ++ 14-ben adtak hozzá. Előtte nem tudtuk használni autoa funkció paramétereit.

Vegye figyelembe, hogy a lambda kifejezést szögletes zárójelben kezdjük []. Meghatározzák a lambda hatókörét - mekkora tekintéllyel rendelkezik a helyi változók és objektumok felett.

A modern C ++ ezen fantasztikus tárházában meghatározottak szerint:

  • [] - nem ragad semmit. Tehát a lambda kifejezésen belül nem használhat egyetlen külső hatókörű helyi változót sem. Csak a paramétereket használhatja.
  • [=]- a helyi objektumokat (helyi változók, paraméterek) érték szerint rögzíti hatókörben. Használhatja őket, de nem módosíthatja őket.
  • [&] - helyi objektumok (helyi változók, paraméterek) referenciával történő befogása a hatókörbe. Módosíthatja őket. Mint a következő példa.
  • [this]- thismutató rögzítése érték szerint.
  • [a, &b]- objektumok rögzítése aérték, bhivatkozás alapján.

Tehát, ha a lambda függvényében szeretné átalakítani adatait valamilyen más formátumba, használhatja a lambdát a hatókör előnyeinek kihasználásával. Például:

A fenti példában, ha [factor]a lambda kifejezésben érték ( ) szerint rögzítettünk helyi változókat , akkor factoraz 5. sorban nem tudtál változtatni . Mert egyszerűen nincs jogod erre. Ne éljen vissza a jogaival! ?

Végül vegye figyelembe val, hogy referenciának vesszük . Ez biztosítja, hogy a lambda függvényen belüli bármilyen változás valóban megváltoztassa a vector.

Inicializálja az utasításokat, ha & kapcsoló

Nagyon tetszett ez a C ++ 17 szolgáltatás azonnal, miután megismertem.

Tehát látszólag most megteheti a változók inicializálását és annak állapotának ellenőrzését - egyszerre a if/switchblokkon belül . Ez nagyon hasznos, hogy a kód tömör és tiszta legyen. Az általános forma:

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

Tegye meg fordítási időben a constexpr

constexpr hűvös!

Tegyük fel, hogy van valamilyen kifejezés, amelyet értékelni kell, és értéke nem változik, ha inicializáljuk. Előre kiszámíthatja az értéket, majd makróként használhatja. Vagy ahogy a C ++ 11 kínálja, használhatja constexpr.

A programozók általában a lehető legnagyobb mértékben csökkentik programjaik futási idejét. Tehát, ha van néhány művelet, akkor a fordítót megteheti, és leveheti a terhelést a futásidőről, akkor a futásidő javítható.

A fenti kód nagyon gyakori példa a constexpr.

Mivel a fibonacci számítási függvényt deklaráltuk constexpr, a fordító előre kiszámíthatjafib(20)fordítási időben. Tehát összeállítás után helyettesítheti a sort

const long long bigval = fib(20);val vel

const long long bigval = 2432902008176640000;

Vegye figyelembe, hogy az átadott argumentum constérték. Ez a deklarált függvények egyik fontos pontja constexpr- az átadott argumentumnak constexprvagy kell lennie const. Ellenkező esetben a függvény normál függvényként fog viselkedni, ami azt jelenti, hogy a fordítási idő alatt nincs előre számítás.

Változók is lehetnek constexpr. Ebben az esetben, mint kitalálhatja, ezeknek a változóknak értékelhetőnek kell lenniük a fordítási időben. Ellenkező esetben fordítási hibát kap.

Érdekes, hogy később a C ++ 17-ben, constexpr-ifésconstexpr-lambdavezették be.

Tollok

Hasonlóan pair, tuplekülönféle adattípusok rögzített méretű értékeinek gyűjteménye.

Néha kényelmesebb használni a std::arrayhelyett tuple. arrayhasonló a sima C típusú tömbhöz, a C ++ standard könyvtár néhány funkciójával együtt. Ezt az adatszerkezetet C ++ 11-ben adtuk hozzá.

Osztálysablon-argumentum levonása

Egy funkció nagyon részletes neve. Az ötlet az, hogy a C ++ 17-ből a sablonok argumentum levonása a szabványos osztálysablonok esetében is megtörténik. Korábban csak a függvénysablonok esetében támogatott.

Ennek eredményeként

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

A levonás típusa implicit módon történik. Ez még kényelmesebbé válik tuple.

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

Ennek a fenti szolgáltatásnak semmi értelme nincs, ha még nem ismeri a C ++ sablonokat.

Intelligens mutatók

A mutatók pokoliak lehetnek.

Annak a szabadságnak köszönhetően, amelyet a C ++ nyelvű nyelvek biztosítanak a programozóknak, néha nagyon könnyű lőni magát. És sok esetben a mutatók felelősek a kárért.

Szerencsére a C ++ 11 intelligens mutatókat vezetett be, amelyek sokkal kényelmesebbek, mint a nyers mutatók. Segítenek a programozóknak abban, hogy megakadályozzák a memória szivárgását azáltal, hogy lehetőség szerint felszabadítják azt. Kivételes biztonságot is nyújtanak.

Arra gondoltam, hogy ebben a bejegyzésben írjak a C ++ intelligens mutatóiról. De látszólag rengeteg fontos részlet van róluk. Megérdemlik a saját bejegyzésüket, és én minden bizonnyal hajlandó vagyok egyet írni róluk a közeljövőben.

Ez minden mára. Ne feledje, hogy a C ++ valójában sokkal több új funkcióval egészítette ki a nyelv legújabb verzióit. Érdemes megnézni őket, ha úgy érzi, hogy érdekli. Itt van egy fantasztikus tárház a modern C ++ -ról, amelyet szó szerint Awesome Modern C ++ néven hívnak!

Adios!