C++14

A C++14 a C++ szabvány ISO/IEC JTC1 változatának  nem hivatalos neve (teljes név: " International Standard ISO/IEC 14882:2014(E) Programming Language C++ ") [1] . A C++14 a C++11 kis kiterjesztésének tekinthető, amely többnyire hibajavításokat és kisebb fejlesztéseket tartalmaz. Az Új Szabványok Fejlesztési Bizottsága 2013. május 15-én tette közzé az N3690 tervezetet [2] . Az N3936 munkatervezet 2014. március 2-án jelent meg, a végső szavazási időszak 2014. augusztus 15-én zárult, az eredményhirdetés (egyhangú jóváhagyás) 2014. augusztus 18-án jelent meg [3] .

Mivel a szabvány fejlesztése hosszadalmas volt, és a végleges verzió kiadásának éve nem volt meghatározva, a fejlesztés során a "C++1y" elnevezést is használták, hasonlóan ahhoz, ahogy a C++11 szabványt "C+"-nak nevezték. +0x" a megjelenés előtt (ennek a verziónak a megjelenése 2010-ig volt várható).

Az alább leírt nyelvi jellemzők az N3797 munkatervezetnek felelnek meg . Ezekben apró eltérések lehetnek a szabvány végleges változatához képest .

Nyelvi változások

Ez a rész a C++14 új alapvető nyelvi funkcióit mutatja be.

Visszatérési típusú következtetés a függvényekhez

A C++11 lehetővé teszi, hogy egy kifejezés visszatérési típusából következtessen a lambda függvények visszatérési típusára. A C++14 ezt a képességet minden funkcióra kiterjeszti. return expression;Az új szabvány a lambda függvények típuskövetkeztetését is leírja, a [4] -től eltérő formában .

Az automatikus visszatérési típus-következtetés használatához egy függvényt úgy kell deklarálni, autohogy visszatérési típusa legyen, de a C++11 visszatérési típus farokspecifikátora nélkül:

auto DeduceReturnType (); // A visszatérési típus később kerül meghatározásra.

Ha több kifejezést ad vissza a függvény törzsének különböző helyein, akkor ezeknek a kifejezéseknek közös kikövetkeztetett típussal kell rendelkezniük [5] .

A return típusú automatikus következtetést használó függvények használhatják a továbbítási deklarációt, de csak definiálásuk után használhatók. Ezeknek a meghatározásoknak ugyanabban a fordítási egységben kell rendelkezésre állniuk, amelyben használják őket.

Lehetséges ilyen függvényekben rekurziót használni , de a rekurzív hívást legalább egy visszatérési érték után kell végrehajtani ebben a függvényben [5] :

automatikus javítás ( int i ) { ha ( i == 1 ) vissza i ; // int visszatérési típusként jelenik meg else return Helyes ( i -1 ) + i ; // most már hívhatod } autoWrong ( int i ) { _ ha ( i != 1 ) return Rossz ( i -1 ) + i ; // nem megfelelő hely a rekurzióhoz. Nincs előzetes visszaküldés. más vissza i ; // az int visszatérési típusként jelenik meg }

Alternatív típusú következtetés a

A C++11 két módszert adott a típusok megállapítására. autolehetővé tette változók létrehozását egy hozzárendelt kifejezésen alapuló típussal. decltypelehetővé tette egy tetszőleges kifejezés eredő típusának meghatározását. Az általuk kikövetkeztetett típusok azonban eltértek egymástól decltype. autoKonkrétan autoa nem hivatkozási típusra mindig úgy következtet, mintha feldolgozva lenne std::remove_reference, míg auto&&mindig egy referenciatípusra következtet. Az eredmény decltypeazonban lehet referencia típusú vagy nem referencia típusú, a feldolgozott kifejezéstől függően [4] :

int i ; int && f (); auto x3a = i ; // decltype(x3a) - int decltype ( i ) x3d = i ; // decltype(x3d) - int auto x4a = ( i ); // decltype(x4a) - int decltype (( i )) x4d = ( i ); // decltype(x4d) - int& auto x5a = f (); // decltype(x5a) - int decltype ( f ()) x5d = f (); // decltype(x5d) - int&&

A C++14 hozzáadta a szintaxist decltype(auto). decltypeEz a szintaxis lehetővé teszi a deklarációs szabályok használatát auto. Ennek csak a kazánkódban van értelme.

A szintaxis decltype(auto)használható visszatérési típusok megállapítására is, ha a függvény visszatérési típusát adjuk meg a hely decltype(auto)helyett [5] . auto

A konstans kifejezésekre vonatkozó korlátozások csökkentése

A C++11 bevezeti a constexpr-functions fogalmát: a fordítási időben végrehajtható függvényeket. Az általuk visszaadott értékek olyan műveletekben használhatók, amelyek állandó kifejezést igényelnek, például sablon argumentumként. A C++11 -ben azonban a constexpr-függvények csak egy visszatérési kifejezést tartalmazhatnak (valamint static_asserttöbb más deklarációt is).

A C++14 nyelvben ezek a korlátozások részben megszűnnek. constexpr-függvények mostantól a következő elemeket tartalmazhatják [4] :

  • Bármilyen bejelentés, kivéve:
    • staticvagy thread_localváltozók;
    • változó deklarációk inicializálók nélkül.
  • Feltételes ági utasítások ifés switch.
  • Minden ciklusutasítás, beleértve fora tartományokra vonatkozókat is.
  • Olyan kifejezések, amelyek megváltoztatják az objektumok értékeit, ha ezeknek az objektumoknak az élettartama a constexpr-függvényben kezdődött. Ez magában foglalja a nem const constexprstatikus tagfüggvények hívásait is.

Az utasítás gotonem megengedett a constexprC++14 -függvényben.

A nem -funkciók hívására vonatkozó korlátozások constexprérvényben maradnak. Így, ha fortartományokhoz használjuk, a függvényeket beginés a endkonténereket túl kell terhelni constexpr-ként. Beépített típus std::initializer_listesetén a függvények constexprként vannak begin/enddefiniálva lokálisan és globálisan is.

Ezenkívül a C++11-ben minden nem statikus metódus, amely -vel deklarált, constexprimplicit módon const-függvényként lett kezelve a függvényhez képest this. Ez a korlátozás megszűnt; A nem statikus metódusok most már nem const[6] . Azonban, mint korábban említettük, egy nem const constexpr-metódus csak akkor tudja megváltoztatni az osztálymezőket, ha az objektum élettartama egy konstans kifejezés kiértékelése során kezdődött.

Változósablonok

A C++ korábbi verzióiban a sablonozás függvényekre és osztályokra korlátozódott. A C++14 lehetővé teszi sablonváltozók létrehozását.

sablon < típusnévT > _ constexpr T pi = T ( 3,1415926535897932385 ); // A szokásos szakosodási szabályok érvényesek: sablon <> constexpr const char * pi < const char *> = "pi" ;

Ebben a példában egy változósablon van definiálva pi, amelyhez hozzá lehet férni a pi értékének különböző típusokhoz való lekéréséhez (például 3egy egész típus olvasásakor; a legközelebbi érték a float, doublevagy long doubleamikor a , illetve a , illetve a olvasása floatsorán doublestb long double.).

Az ilyen deklarációk és meghatározások magukban foglalják a szokásos sablonszabályokat, beleértve a specializációs szabályokat [7] [8] .

Osztályok összesített inicializálása mezőinicializálókkal

A C++11 bevezette az osztálymező-inicializálókat, amelyek olyan kifejezések, amelyek osztályszintű mezőkre vonatkoznak, ha a konstruktor nem inicializálja azokat önállóan. Az aggregátumok definíciója megváltozott, hogy kifejezetten kizárja az összes taginicializálóval rendelkező osztályt, így az összesített inicializálás nem volt lehetséges számukra.

A C++14 eltávolítja ezt a korlátozást [4] , és lehetővé teszi az osztályok összesített inicializálását mezőinicializálókkal. Ha a kapcsos zárójelben lévő inicializálók listája nem ad értéket ehhez az argumentumhoz, akkor a mező inicializálója [9] átveszi az irányítást .

Bináris literálok

A C++14 numerikus literáljai bináris formában adhatók meg [4] . A szintaxis a 0bvagy előtagokat használja 0B. Hasonló szintaxis használatos a Java , Python , Perl és D nyelvekben is .

Ezer elválasztó

A C++14-ben az aposztrófot használhatjuk a bitek tetszőleges elválasztására numerikus literálokban [10] . Egyes esetekben ez leegyszerűsíti a nagy numerikus állandók észlelését a kódban, és javítja a kód olvashatóságát.

auto integer_literal = 1'000'000 ; auto floating_point_literal = 0,000'015'3 ; auto binary_literal = 0b0100'1100'0110 ; auto silly_example = 1'0'0'000'00 ;

Általános lambda függvények

A C++11-ben a lambda függvény paramétereit meghatározott típusokkal kellett deklarálni. A C++14 megszünteti ezt a korlátozást, és lehetővé teszi a lambda függvény paramétereinek deklarálását egy típusspecifikátorral auto[7] .

auto lambda = []( auto x , auto y ) { return x + y ;};

Az általános lambda-függvények paramétereinek típuskövetkeztetése hasonló szabályokat követ, mint a auto-változók típuskövetkeztetése (de nem teljesen azonos). A fenti kód egyenértékű a következővel [11] :

struct unnamed_lambda { sablon < típusnév T , típusnév U > auto operátor ()( T x , U y ) const { return x + y ;} }; auto lambda = unnamed_lambda ();

Kifejezések rögzítése lambda függvényekhez

A C++11 lambda függvények lehetővé teszik a külső hatókörben deklarált változók rögzítését referencia vagy érték szerinti átadással. Ez azt jelenti, hogy nem lehet érték szerint rögzíteni olyan típusú változókat, amelyek csak áthelyezhetők (de nem másolhatók) [12] . A C++14 lehetővé teszi változók rögzítését tetszőleges kifejezés inicializálással. Ez lehetővé teszi a változók értékmozgással történő rögzítését és a magasabb hatókörben nem deklarált nevű változók deklarálását [7] .

A kifejezések rögzítése inicializálók segítségével történik:

auto lambda = [ érték = 1 ] { visszatérési érték ;};

A lambda függvény lambda1-et ad vissza, mert valuea megfelelő inicializáló aktiválódott a paraméterhez. A rögzített paraméter típusára az inicializátor típusából következtet a rendszer, hasonlóan ahhoz, mintha egy változót a specifikátorral deklarálnánk auto.

Ez a funkció használható mozgás közbeni rögzítésre a szabványos funkció használatával std::move:

auto ptr = make_unique < int > ( 10 ); auto lambda = [ érték = std :: move ( ptr )] { return * érték ;};

Attribútum [[deprecated]]

Az attribútum deprecatedlehetővé teszi az entitások elavultként való megjelölését. Ezek az entitások továbbra is elérhetők, de fordítási időre figyelmeztet a rendszer. Az argumentum deprecatedlehet egy karakterlánc , amely megmagyarázza az elavulás okát és/vagy a lehetséges cserét.

[[ elavult ]] intf ( ); [[ elavult ( "g() nem szálbiztos. Használja a h()-t a g() helyett" )]] void g ( int & x ); void h ( int & x ); érvénytelen teszt () { int a = f (); // figyelmeztetés: 'f' elavult g ( a ); // figyelmeztetés: 'g' elavult: g() nem szálbiztos. Használja a h()-t g() helyett }

Új funkciók a szabványos könyvtárban

Megosztott mutexek és zárak

A C++14 megosztott mutexet és új zártípust ad hozzá [13] [14] .

Heterogén keresés asszociatív tárolókban

A C++ Standard Library négy asszociatív tárolóosztályt határoz meg. Ezek az osztályok lehetővé teszik a felhasználó számára, hogy az adott típusú értékek alapján keressen értékeket. A térképtárolók lehetővé teszik a felhasználó számára, hogy kulcsot és értéket adjon meg, miközben keres a kulcson, és visszaadja az értéket. A keresés azonban mindig egy bizonyos típusú kulcson történt, legyen az a kulcs, mint a térképen, vagy maga az érték, mint a készletben.

A C++14 lehetővé teszi az asszociatív konténerek tetszőleges típusú értékkel történő indexelését, feltéve, hogy van egy túlterhelt összehasonlító operátor, amely össze tudja hasonlítani az adott típus értékét a tároló kulcstípusának értékével [15] . Ez lehetővé teszi a kulcstípussal rendelkező leképezési tárolók típuskifejezések szerinti indexelését std::stringa const char*túlterhelt összehasonlító operátor használatával operator<.

A visszamenőleges kompatibilitás fenntartása érdekében a heterogén keresések csak akkor engedélyezettek, ha az asszociatív tárolónak átadott összehasonlító támogatja az ilyen keresést. Szabványos könyvtárosztályok std::less(alapértelmezett a halmaz- és leképezési konténereknél), és std::greaterlehetővé teszik a heterogén kereséseket [16] .

Szabványos, felhasználó által definiált literálok

A C++11-nek van szintaxisa a felhasználó által definiált literális utótagokhoz, de egyiket sem használják a szabványos könyvtárban. A C++14 a következő szabványos literálokat adja hozzá [15] :

  • "s" különböző std::basic_stringtípusok létrehozásához.
  • "h", "min", "s", "ms", "us" és "ns" a megfelelő időintervallumok létrehozásához std::chrono::duration.
string str = "hello world" s ; chrono :: időtartam dur = 60 s ;

A két "s" literál nem hat egymásra, mert a string literál csak karakterláncokon működik, míg a második literál csak számokon [17] .

Sorok címzése típus szerint

std::tupleA C++11-ben bevezetett, több beírt érték összesítését teszi lehetővé, amelyeket a fordításkor indexelünk. A C++14 kibővíti a sorok funkcionalitását, hogy lehetővé tegye a tuple elemeinek elérését nem csak index, hanem típus szerint is [15] . Ha a tuple egynél több elemet tartalmaz a kért típusból, a keresés fordítási idejű hibát eredményez [18] :

tuple < string , string , int > t ( " foo " , " bar " , 7 ); int i = get < int > ( t ); // i == 7 int j = get < 2 > ( t ); // ugyanaz, mint korábban: j == 7 string s = get < string > ( t ); // fordítási idő hiba a kétértelműség miatt

Egyéb változtatások a szabványos könyvtárban

std::make_uniqueugyanúgy használható, mint std::make_sharedaz objektumoknál std::unique_ptr[7] .

Túlterhelés std::integral_constanthozzáadásához operator(), amely állandó értéket ad vissza [15] .

A globális függvényekkel analóg módon olyan függvényeket std::begin/std::endadtunk hozzá std::cbegin/std::cend, amelyek az állandó iterátorokat a tartomány elejére és végére adják vissza.

Jegyzetek

  1. ISO/IEC 14882:2014 - Információtechnológia - Programozási nyelvek - C++ . ISO (2014. január 14.). Hozzáférés dátuma: 2015. január 26. Az eredetiből archiválva : 2017. január 29.
  2. Bizottsági tervezet, szabvány a C++ programozási nyelvhez (PDF). ISO (2013. május 15.). Letöltve: 2014. július 24. Az eredetiből archiválva : 2022. január 21..
  3. Sutter, Herb (2014. augusztus 18.), Megvan a C++14! , < https://isocpp.org/blog/2014/08/we-have-cpp14 > . Letöltve: 2014. augusztus 18. Archiválva : 2014. augusztus 19. a Wayback Machine -nél 
  4. 1 2 3 4 5 Wong, Michael The View from the C++ Standard meeting, 2013. április 3. rész . C/C++ Cafe (2013. április 30.). Letöltve: 2013. június 14. Az eredetiből archiválva : 2013. október 13..
  5. 1 2 3 Merrill, Jason N3638 Visszatérési típusú levonás normál funkciókra (5. változat) (2013. április 17.). Letöltve: 2013. június 14. Az eredetiből archiválva : 2013. augusztus 25..
  6. Smith, Richard N3652 A constexpr függvények korlátainak enyhítése (2013. április 18.). Letöltve: 2014. július 24. Az eredetiből archiválva : 2013. augusztus 25..
  7. 1 2 3 4 Sutter, Emblem Trip Report: ISO C++ 2013. tavaszi találkozó . isocpp.org (2013. április 20.). Letöltve: 2013. június 14. Az eredetiből archiválva : 2017. augusztus 20..
  8. Dos Reis, Gabriel N3651 Változósablonok (1. változat) (PDF) (2013. április 19.). Letöltve: 2014. július 24. Az eredetiből archiválva : 2013. augusztus 25..
  9. Vandevoorde, Daveed; Voutilainen, Ville N3653 Taginicializálók és aggregátumok (2013. április 17.). Letöltve: 2014. július 24. Az eredetiből archiválva : 2013. augusztus 25..
  10. Crowl, Lawrence; Smith, Richard; Snyder, Jeff; Vandevoorde, Daveed N3781 Egyetlen idézőjel számjegyelválasztóként (2013. szeptember 25.). Letöltve: 2014. október 15. Az eredetiből archiválva : 2014. április 13..
  11. Faisal, Vali; Sutter, Herb; Abrahams, Dave N3649 Általános (polimorf) Lambda-kifejezések (3. változat) (2013. április 19.). Letöltve: 2014. július 24. Az eredetiből archiválva : 2013. augusztus 25..
  12. Mozgatás rögzítés Lambdában . verem túlcsordulás . Letöltve: 2014. július 24. Az eredetiből archiválva : 2013. január 24..
  13. Wong, Michael The View from the C++ Standard meeting 2013. április 3. rész . C/C++ Cafe (2013. április 30.). Letöltve: 2013. június 14. Az eredetiből archiválva : 2013. október 13..
  14. Howard, Hinnant; Vollmann, Detlef; Boehm, Hans N3659 Megosztott zárolás C++-ban (2. változat) (2013. április 19.). Letöltve: 2014. július 24. Az eredetiből archiválva : 2013. augusztus 19..
  15. 1 2 3 4 Wong, Michael The View from the C++ Standard meeting 2013. április 2. rész . C/C++ Cafe (2013. április 26.). Letöltve: 2013. június 14. Az eredetiből archiválva : 2013. október 13..
  16. N3657 Heterogén összehasonlító keresés hozzáadása asszociatív tárolókhoz (4. rev.) (2013. március 19.). Letöltve: 2014. július 24. Az eredetiből archiválva : 2013. augusztus 19..
  17. Peter, Sommerlad N3642 Felhasználó által definiált literálok szabványos könyvtártípusokhoz (1. rész – 4. verzió) (PDF) (2013. április 18.). Letöltve: 2014. július 24. Az eredetiből archiválva : 2013. augusztus 25..
  18. Spertus, Mike N3670 A sorok típus szerinti megszólításának megfogalmazása: 2. változat (2013. április 19.). Letöltve: 2014. július 24. Az eredetiből archiválva : 2013. augusztus 19..