C++17

Kokeneet kirjoittajat eivät ole vielä tarkistaneet sivun nykyistä versiota, ja se voi poiketa merkittävästi 5. toukokuuta 2021 tarkistetusta versiosta . tarkastukset vaativat 17 muokkausta .

C++17 (tunnetaan myös nimellä C++1z) on C++-standardin ISO /IEC-version nimi. C++17:n tekniset tiedot julkaistiin joulukuussa 2017 [1] [2] .

Vakion arvoksi __cpluspluson tullut 201703L, tätä käytetään ehdolliseen käännökseen .

Poistettu tai kielletty

Trigrafit poistettu

Trigrafeja käytettiin koneissa, joissa oli ei-standardikoodaus ja/tai rajoitetut näppäimistöt. 80-luvun lopulla 8-bittisten koodausten ja halpojen kumikalvonäppäimistöjen leviämisen myötä trigrafit itse asiassa menettivät merkityksensä, ja 30 vuotta myöhemmin ne jätettiin luonnollisesti pois [3] [4] .

// Suoritetaanko seuraava rivi??????????????????/ a ++ ; /* trigrafeilla tämä rivi on kommentoitu - trigrafi ??/ vastaa \ */

Poistettu rekisteriavainsana

C-kieli oli "portable assembler": sen avulla pystyttiin tekemään nopeita ohjelmia, jotka käännetään eri tietokoneille, ja se käytti myös assembler-apuohjelmia ( linker , librarian). Käsitteet, kuten " otsikkotiedosto " ja " käännösyksikkö ", ovat kaikuja noista ajoista.

Sana registeryhdistettiin alun perin ohjelman manuaaliseen optimointiin. Nykyaikaiset kääntäjät "konepellin alla" tekevät valtavan määrän optimointeja, ja tällainen manuaalinen ohjaus näyttää tarpeettomalta. C++11:ssä sana julistettiin ei-toivotuksi. Sana on edelleen varattu ja sitä voidaan joskus käyttää eri tarkoitukseen - kuten C++11:ssä [5] . auto

Poistettu ++-toiminto boolille

Toiminta on ilmeisen vaarallista ja kielletty C++98:ssa [6] . Operaatio --puuttuu.

Ilmoitetut poikkeukset poistettu

Ilmoitetut poikkeukset void f() throw(A, B, C);, jotka löytyvät esimerkiksi Javasta , tekevät enemmän haittaa kuin hyötyä. Kielletty C++11:ssä, poistettu C++17:ssä. Pysyi throw()synonyyminä sanalle noexcept(true)[7] .

Poistettu tyypit ja toiminnot, jotka korvattiin (ja kiellettiin) C++11:ssä

Niiden joukossa on std::auto_ptrvanhoja std::random_shuffletoiminnallisia sovittimia [8] [9] .

Sen sijaan käytetään unique_ptr, shuffleja uusia funktiomalleja, jotka perustuvat function/ -merkkiin bind. Väitetään, että mikä tahansa koodi auto_ptrvoidaan muuntaa mekaanisesti muotoon unique_ptr, yksinkertaisella lisäyksellä, std::movejos omistusoikeus siirtyy.

iostreamMyös C++98:ssa [10] kielletyt erilliset osat on poistettu .

Poistettu std::funktion konstruktorit, jotka ottivat allokaattorin

Yhteensä viisi ylikuormitusta, mukaan lukien tämä

malli < classAlloc > _ function ( std :: allocator_arg_t , const Alloc & alloc ) noexcept ;

Käsittämättömän semantiikan ja toteutusvaikeuksien vuoksi ne poistettiin ilman ennakkokieltoa [11] .

Vakiokirjaston erittäin harvinaiset ominaisuudet ovat kiellettyjä

Useat harvinaiset ominaisuudet standardikirjastosta ovat kiellettyjä: [12] [13] [14]

  • allocator<void> - osoittautui lunastamatta;
  • jotkin toiminnot allocator ovat päällekkäisiä mallissa allocator_traits;
  • raw_storage_iterator - ei kutsu rakentajia ja siksi sen käyttö on rajoitettua;
  • get_temporary_buffer - siinä on selviä sudenkuoppia;
  • is_literal_type - hyödytön geneeriselle koodille, mutta jätetään niin kauan kuin C++:ssa on käsite "kirjaimellinen tyyppi";
  • iterator - iteraattoreita on helpompi kirjoittaa tyhjästä kuin rakentaa sen päälle;
  • codecvt - itse asiassa se toimi erittäin huonosti, valiokunta vaati erikoiskirjastojen käyttöä;
  • shared_ptr::unique() - epäluotettavuuden vuoksi monisäikeisessä ympäristössä.

He lupaavat poistaa ne kokonaan C++20:ssa.

Uusiin C++17-toimintoihin liittyvät kiellot

  • result_of→ invoke_resulton yksinkertaisempi syntaksi, joka perustuu C++11-tyyppiseen päättelyyn [15] ;
  • bool uncaught_exception()→ int uncaught_exceptions() - yhden poikkeuksen käsittelyssä järjestelmä voi heittää toisen, jolloin useat poikkeukset voivat "roikkua" käsittelemättä. Tarkastaa, kuinka monta niistä oli konstruktorissa ja kuinka monta oli destruktorissa, on käytettävissä olevien kirjastojen kannalta luotettavampi ja "vapaa" tapa määrittää, heitetäänkö destruktorista poikkeus vai ei [16] [ 17] [18] .

Poistettu C-kirjaston otsikot

Kun siirrytään C11:een, otsikkotiedostot <ccomplex>, <cstdalign>, <cstdbool>, <ctgmath>. Tiedosto <ciso646>ei ole kielletty [19] .

autox{}; ei enää luo alustusluetteloa

C++11:een lisätyn yleisen alustuksen int x{};avulla voit luoda objektin, rakenteen, taulukon yhdellä syntaksilla. C++17:ssä on selvennetty: jos tyypin sijasta se seisoo , autokäyttäjä haluaa luoda yhden objektin, eikä aloituslistaa tarvita.

Samaan aikaan se auto x = {1, 2, 3};jatkaa luomista: toisaalta yhteensopivuuden vuoksi , toisaalta for (auto x : {1, 2, 3})yhdelle objektille on auto x = 1;[20] [9] .

auto x1 = { 3 }; // std::initializer_list<int> auto x2 { 1 , 2 }; // virhe nyt auto x3 { 3 }; // int

Globaalit muutokset

Poikkeusmääritys on nyt osa tyyppijärjestelmää

Toiminnot ja  ovat nyt eri tyyppisiä toimintoja (mutta eivät voi muodostaa ylikuormitettua joukkoa). Tämän ansiosta API voi vaatia takaisinsoittoja , jotka eivät tee poikkeuksia, sekä optimoida koodin nonelle [21] . void f() noexcept(true);void f() noexcept(false);

Uusi ylitasattu

C++11 esitteli mahdollisuuden luoda tietorakenteita, joiden kohdistus on suurempi kuin teoreettinen. Tämä mahdollisuus on otettu käyttöön uudessa operaatiossa [22] .

luokka alignas ( 16 ) float4 { float f [ 4 ]; }; float4 * p = uusi float4 [ 1000 ];

Uudessa operaattorissa oli ylikuormitus lisäparametrilla, joka kohdistaa oikein ylikohdistetun objektin muistissa.

Kopioinnin pakollinen hävittäminen

Prvalue-käsitteen merkitys on muuttunut: nyt se on vain alustus.

Vaikka koodi SomeType a = 10;vaatii edelleen sekä konstruktorin että =-operaattorin, vain rakentaja kutsutaan taatusti.

Tämä tarkoittaa, että funktiot voivat palauttaa tyyppejä, joita ei voi kopioida ja siirtää.

Tiukempi arviointijärjestys

Nyt operaatiot a.b, a->b, a->*b, a(b1, b2, b3), b += a(ja analogit muille operaatioille), a[b], a << bja a >> barvioidaan järjestyksessä a → b sivuvaikutusten pitämiseksi hallinnassa [23] .

Jos niitä kutsutaan funktioiksi (esimerkiksi operator += (a, b)), järjestys pysyy määrittelemättömänä.

Laajensi käsitettä "vakio mallissa"

On malleja, jotka hyväksyvät vakion.

malli < int N > struct Array { int a [ N ]; };

Mikä voi olla vakio N ja mikä ei - ilmoitetaan päinvastoin. Mallin vakio ei voi olla osoitin kenttään, tilapäinen objekti, merkkijonoliteraali, tulos typeidtai vakiomuuttuja __func__[17] [24] ;

Sillä voi olla erityyppinen alku ja loppu

Nyt for (auto v : x)tarkoittaa eri tyyppisten alun ja lopun sallimista. auto __begin = begin-expr; auto __end = end-expr;

Tämä on perusta alueiden iteraatiolle, mikä on keskeneräistä työtä [25] .

Toimitukselliset muutokset

"Jatkuvan iteraattorin" käsite

Std::vector- ja std::string- taulukot käsittelevät muistin vierekkäisiä alueita. He esittelivät käsitteen "jatkuva iteraattori" [26] [27] . Käsitteellisesti mikään ei ole muuttunut.

He antoivat myös määritelmiä muille käsitteille - edelleenlähetysviittaus , oletusjäsenen alustus , mallikokonaisuus . Tämä on työtä C++20 - konseptien parissa.

Merkit u'x' ja U'x', joita ei ole koodattu yhdellä merkillä, ovat kiellettyjä

Aikaisemmin tämä käyttäytyminen määriteltiin toteutuksessa.

Samaan aikaan he tekivät "UTF-8-merkkejä", joilla on tyyppi ja jotka voivat sisältää koodeja 0-127, kuten UTF-8-merkkijonot - ilmeisesti niin, että ohjelma on vähemmän riippuvainen tietokoneen alue-asetuksista [ 17] [28] . char

Tilapäisesti pois käytöstä memory_order_consume

Puutteellisen semantiikan vuoksi "kulutta" -tilausmenetelmä kiellettiin suullisesti (ilman merkkiä ) ja kehotettiin käyttämään "hankita" -menetelmää. Työ uuden semantiikan parissa on edelleen kesken, ja ehkä kielto jonain päivänä puretaan [29] . [[deprecated]]

Joka tapauksessa PowerPC :ssä ja ARM :ssa kaikki lataukset kuluttavat automaattisesti , mutta kaikki eivät hanki , ja kulutusmenetelmä voi säästää kelloja monialustaisessa koodissa [30] .

Kieli

static_assert yhdellä argumentilla

Jos static_assertse ei toimi, ei aina tarvitse kertoa ohjelmoijalle, mikä on vialla - usein hän voi itse selvittää sen kontekstista. [31] .

static_assert ( koko ( wchar_t ) == 2 );

inline globaaleille muuttujille ja vakioille

Nyt voit kirjoittaa otsikkotiedostoon ja kun tämä tiedosto sisällytetään cpp-tiedostoihin, ne kaikki viittaavat samaan objektiin (luokan rakentajaa ei kutsuta toistuvasti jokaiselle cpp-tiedostolle, toisin kuin tai ), inline const ClassName INSTANCE_NAMEconst ClassName INSTANCE_NAMEstatic const ClassName INSTANCE_NAME

Uudet vakiomerkinnät

  • [[fallthrough]]: yhdessä operaattorin osiossa switch"pudotaan" tarkoituksella seuraavaan. Duff-laitteen mahdollinen toteutus
int n = ( luku + 7 ) / 8 ; if ( ! count ) return ; kytkin ( count % 8 ) { tapaus 0 : tee { * to = * ++ ; _ [[ fallthrough ]]; tapaus 7 : * - = * ++ ; _ [[ fallthrough ]]; tapaus 6 : * - = * ++ ; _ [[ fallthrough ]]; tapaus 5 : * - = * ++ ; _ [[ fallthrough ]]; tapaus 4 : * - = * ++ ; _ [[ fallthrough ]]; tapaus 3 : * - = * ++ ; _ [[ fallthrough ]]; tapaus 2 : * - = * ++ ; _ [[ fallthrough ]]; tapaus 1 : * - = * ++ ; _ } while ( -- n > 0 ); }
  • [[nodiscard]]: funktion kutsumista proseduurina pidetään virheenä - se on esimerkiksi "puhdas" funktio, kuten string::empty()[32] , jonka ainoa tehtävä on palauttaa arvo, tai objektiprotokolla vaatii jotain tekemistä palautetulle arvolle, kuten unique_ptr::release(). Myöhemmässä C++20 -standardissa tuli mahdolliseksi määrittää syy, miksi puhelu epäonnistui.
luokka SmartPtr { // ainutlaatuisen_ptr :n julkisen oma toteutus : /// Siirtää hallitun objektin manuaaliseen ohjaukseen /// @palauttaa osoittimen hallittuun objektiin [[ nodiscard ]] Hyötykuorma * release (); }; SmartPtr p ; Hyötykuorma * data = p . vapauttaa (); // älykäs osoittimen oikea käyttö tietojen poistaminen ; p . vapauttaa (); // varoitus: 'SmartPtr::release()':n palautusarvon huomiotta jättäminen, joka on ilmoitettu attribuutilla nodiscard ( void ) p . vapauttaa (); // näin he hiljentävät varoituksen
  • [[maybe_unused]]: jossakin käännöstiloissa ( Windows / POSIX , debug/release) tätä tai toista elementtiä ei käytetä, eikä tämä ole virhe.
// QString on aina UTF-16 ja wstring käyttöjärjestelmästä riippuva malli < int Sz > void append ( QString & s , allekirjoittamaton pitkä ch ); // Windows-versio, wstring = UTF-16 malli <> [[ ehkä_unused ]] inline void append < 2 > ( QString & s , allekirjoittamaton pitkä ch ) { s . append ( static_cast < uint16_t > ( ch ); } // POSIX-versio, wstring = UTF-32 malli <> [[ ehkä_unused ]] void append < 4 > ( QString & s , allekirjoittamaton pitkä ch ) {} // koodipaikan koodaus UTF-16:ssa, jätä pois lyhyyden vuoksi std :: wstring s = L " \U0001F60E " ; // hymiö silmälaseilla QString r ; // Lyhyyden vuoksi teemme tarkan kopion, eikä niin monimutkaista koodia tarvita. // Mutta joskus sitä tarvitaan jossain prosessoinnissa - esimerkiksi irtomerkkejä. for ( auto c : s ) liittää < ( c ) koko > ( r , c ); Tai parametria ei ole tarkoituksella käytetty, mutta nimi jätetään dokumentointia varten. luokka ISoccerSeason { // julkinen käyttöliittymä : /// @pre molemmat joukkueet osallistuvat tällä kaudella. /// @return true, jos ottelu pelataan koti- ja vierasjoukkueiden välillä /// @varoitus Tyypillisellä jalkapallokaudella molemmat joukkueet pelaavat sekä koti- että vierasjoukkueita vastaan. virtual bool doTeamsPlay ([[ ehkä_unused ]] const Joukkue & koti , [[ ehkä_unused ]] const Joukkue & vieras ) const { return true ; } virtuaalinen ~ ISoccerSeason () = oletus ; };

Tyypinimen käyttäminen sisäkkäisissä malleissa

C++-kielen puute: malleissa typenameja classjoissain paikoissa ei ole vaihdettavissa [33] .

malli < malli < tyypin nimi > luokka X > struct C ; // OK malli < malli < tyypinnimi > tyypin nimi X > struct D ; // ei käännä

Molemmat avainsanat on nimenomaisesti ilmoitettu keskenään vaihdettavissa oleviksi.

Rakenteellinen linkitys

Uusi tapa ilmoittaa muuttujat monimutkaisten objektien purkamiseksi on syntynyt, nimeltään rakennesidonta [34] .

auto [ paikka , oliLisätty ] = someMap . emplace ( avain , arvo );

Toimii pareille, ketjuille ja muille tyypeille, joissa . std::get

Nimitilan A::B merkintä

Sisäkkäisten nimiavaruuksien määritelmä: [9] [35] namespace A::B {} lyhenteenä sanalle namespace A { namespace B {} };

Nimiavaruuksien ja lueteltujen elementtien merkinnät

Esimerkiksi:

enum luokka TriBool { EI , ehkä , KYLLÄ , NN [[ ehkä_unused ]], ERITTÄMÄTTÖMÄN [[ poistettu käytöstä ( "Nimetty uudelleen MAYBE" )]] = EHKÄ }; constexpr int TriBool_N = static_cast < int > ( TriBool :: NN ); const char * triBoolNames [ TriBool_N ] = { "ei" , "ehkä" , "kyllä" };

Ilmoitettua tavoitetta ei vielä ole [17] [36] , mutta tämä antaa kääntäjien kehittäjille mahdollisuuden keksiä yksi - esimerkiksi julistaa, että NN-elementti on erityinen eikä sitä tarvitse määrittää muuttujiin, jotka käsitellään switch.

Jos käännettäessä

SFINAE - konsepti mahdollisti yksinkertaisen mallipohjan enable_if, joka tarjoaa erilaisia ​​toimintoja eri tyypeille, mutta antaa raskaan koodin. C++17:ssä voit yksinkertaistaa ohjelmaa: operaattori if constexpr(expression)instantoi koodin, jos suluissa oleva lauseke on tosi [37] .

malli < luokkaT > _ constexpr T absoluuttinen ( T arg ) { paluu arg < 0 ? - arg : arg ; } malli < luokkaT > _ constexpr auto tarkkuuskynnys = T ( 0,000001 ); malli < luokkaT > _ constexpr bool close_enough ( T a , T b ) { if constexpr ( on_kelluva_piste_v < T > ) // << !! palauttaa absoluuttisen ( a - b ) < tarkkuuskynnys < T > ; muu palauttaa a == b ; }

Tässä tapauksessa varmistamme, että murtolukujen välinen ero on pieni ja että kokonaislukujen tasa-arvo tarkistetaan.

Yksinkertaistettu syntaksi binääritoiminnalle muuttujamalleissa

Pakatut lausekkeet [17] [38] :

malli < typename ... As > bool foo ( As ... args ) { return ( args && ...); }

Murtolukujen heksadesimaaliesitys

Heksadesimaali mantissa ja desimaalieksponentti: 0xC.68p+2, 0x1.P-126, samanlainen kuin substituutio %a. C on tukenut tätä syntaksia versiosta 99 lähtien [39] .

Paikallisen muuttujan alustus if/switchissä

Paikallisten muuttujien alustuksen fortapaan tekee koodista kompaktimman [40] .

if ( auto it = m . find ( key ); it != m . end ()) return it -> second ;

Käyttämällä määritteissä

// Oli mitätön f () { [[ rpr :: kernel , rpr :: target ( cpu , gpu )]] // toista do_task (); } // Tuli mitättömäksi f () { [[ käyttäen rpr : ydin , kohde ( cpu , gpu )]] tee_tehtävä (); }

Tyyppittömät parametrit malleissa

Mahdollistaa minkä tahansa mallin parametrien asettamisen [41] :n kautta . auto

malli < auto X > struct B { staattinen constexpr auto arvo = X ; }; B < 5 > b1 ; // OK: mallin parametrityyppi on int B < 'a' > b2 ; // OK: mallin parametrityyppi on char B < 2.5 > b3 ; // virhe: mallin parametrityyppi ei voi olla kaksinkertainen

Siepataan lambda-objektia *tätä

Oli: . Siitä tuli: [42] . [self = *this]{ self.f(); }[*this]{ f(); }

Voit alustaa enum-luokan numerolla

enum classjoskus käytetään tekemään toisesta kokonaislukutyypistä, joka ei ole yhteensopiva minkään kanssa. Nyt tämän tyyppiset muuttujat voidaan alustaa numeroilla [43]

enum class Kahva : intptr_t { VIRHEELLINEN = 0 }; Kahva h { 42 }; Kahva h = 42 ; // kielletty

Kirjasto

Pieniä parannuksia kirjastoon

  • Jatkuva ylikuormitus string::data. Käytetään kutsumaan matalan tason merkkijonofunktioita, jotka ottavat tietyn pituisen muistinpalan ja täyttävät sen merkeillä (esim. WinAPI ). Ennen C++11:tä sitä käytettiin const_cast<char*>(x.data()), ennen C++17:ää se oli &x.front().
  • emplace_backyksi elementti palauttaa viitteen. Voit kirjoittaa jotain tällaista:
v . emplace_back ( "alpha" , "bravo" ). tee jotain ();
  • C-standardikirjasto on päivitetty C99 :stä C11 :een [44] .
  • Toiminnot std::size(x), std::begin(x), std::end(x), std::empty(x). Mahdollistaa yhteisen yleiskoodin kirjoittamisen STL-säiliöille ja -taulukoille [26] [45] . Lisäksi std:: size on välttämätön funktio, joka usein kirjoitettiin yksinään virheineen.
  • Lisätty osittainen erikoistuminen [46]bool_constant<bool B> = integral_constant<bool, B>;
  • Lisätty ominaisuusfunktiot SFINAE : lle: , , , , (yhdistetty tyyppi), (triviaalisti kopioitava objekti ja millä tahansa kahdella objektilla, joilla on sama arvo, on sama sisäinen esitys).is_swappableis_nothrow_swappableis_swappable_withis_nothrow_swappable_withis_aggregatehas_unique_object_representations
  • Laajennettu kirjasto alustamattoman muistin kanssa työskentelemiseen. On olemassa funktioita , , , , , sekä niiden versioita n elementille.uninitialized_default_constructuninitialized_value_constructuninitialized_movedestroydestroy_at
  • Uusi malli . Yksinkertaistaa SFINAE- mallien luomista, joita voidaan laajentaa, jos tyyppi T on olemassa [47] .void_t<T> = void
  • Lisätty versio Finder-objektilla . Hakuja on oletuksena kolme: Alkueläin, Boyer-Moore ja Boyer-Moore-Horspool .std::search
  • Uusi funktio alustaa tyypin T monikon tiedoilla.make_from_tuple
  • Uusi vakio määrittää, onko atomimuuttuja ei-esto .atomic::is_always_lock_free
  • Lisätty toiminnot pyöristämiseen ylös, alas ja lähimpään .chrono
  • Lisäsimme elementtien pudotuksen ( ) ja erottamisen ( ) funktiot.map/setmergeextract
  • Lisätty tyyppi .shared_ptr<T>::weak_type = weak_ptr<T>
  • Joissakin tapauksissa allokaattoreiden tyyppi voi olla epätäydellinen. Nyt rekursiiviset rakenteet, kuten . Suuret kääntäjät ovat tukeneet tätä pitkään, on vain täsmennettävä se.struct X { std::vector<X> data; };
  • Lisätty implisiittiset konstruktorit ja .pairtuple
  • unique_ptr/shared_ptrvoi toimia C-tyylisten taulukoiden kanssa ( ). C++14:ssä piti vetää oikea poistotoiminto ( ).shared_ptr<string[]>(new string[n])shared_ptr<string[]>(new string[n], default_delete<string[]>() )
  • Työtä [48] [49] on jalostettu .common_type

Uusi tyyppi std::string_view

Usein tapahtuu, että joudut välittämään muuttumattoman merkkijonon toiseen koodin osaan, tämä voidaan tehdä seuraavilla tavoilla:

void doSmth ( const char * s ); // entä jos merkkijonossa on tyhjä merkki? Kyllä, ja funktion sisäosista tulee virheellisiä void doSmth ( const std :: string & s ); // entä jos merkkijono ei ole merkkijono ja meidän on varattava muistia?

C++17 esitteli tyypin string_view – merkkijonon, jolla on vain osoitin ja pituus, ei omistajuutta, ei muistinhallintaa eikä edes päättävää nollaa – joten siinä ei ole c_str(). Vain reunuksia (alku/pituus) voidaan muuttaa, ei merkkejä. Ohjelmoijan tehtävänä on varmistaa, että objekti ei ylitä sitä muistipuskuria, johon merkkijono on tallennettu, ja parametrien välittäminen on sille hyvää käyttöä. Objekti string_viewon hyvin pieni (2-bittinen kone), ja se tulisi välittää arvon perusteella viittauksen sijaan.

string_viewitsessään on abstraktio - se abstrahoi pois merkkijonojen tallennusmenetelmän, mikä vaatii vain yhtä asiaa - että tekstidata on peräkkäisiä tavuja muistissa. Vain monimutkaiset epätavalliset rakenteet (esimerkiksi hihna/köysi ) tallentavat satunnaisia ​​merkkijonoja. Ja kaikki loput - ja , ja , ja erilaiset taulukot - muunnetaan muotoon . stringconst char*string_view

Välimuistin rivin koko

On olemassa kaksi uutta vakiota hardware_constructive_interference_sizeja hardware_destructive_interference_size. Siten käyttäjä voi välttää väärän jakamisen (destruktiivinen häiriö) ja parantaa paikallisuutta (konstruktiivinen häiriö).

struct keep_apart { alignas ( hardware_destructive_interference_size ) atomic < int > cat ; alignas ( hardware_destructive_interference_size ) atomic < int > dog ; // kissa on kaukana koirasta, niitä voi vaihtaa eri säikeistä. }; struct -together { atomi < int > koira ; int pentu ; }; struct kennel { //... alignas ( sizeof ( yhdessä )) together pack ; //... }; static_assert ( koko ( yhdessä ) <= laitteiston_rakentava_häiriön_koko ); // varmista, että yhdessä on yksi välimuistirivi.

Teoriassa molempien vakioiden pitäisi olla samat, mutta heterogeenisten arkkitehtuurien tukemiseksi päätettiin tehdä kaksi vakiota. [viisikymmentä]

Uusi share_mutex-tyyppi

Mutex, jonka avulla voit lukea rinnakkain ja kirjoittaa yhdelle [51] . Sen estoaineita kutsutaan nimellä shared_lockja unique_lock.

Automaattinen säilön parametrityypin tunnistus

Kirjastossa ilmestyi funktioita, niin sanottuja vähennysoppaita , joiden avulla voit tehdä tämän:

std :: pari p ( 2 , 4,5 ); // yksi std :: vektori < int > v = { 1 , 2 , 3 , 4 }; std :: vektori x ( v.alku ( ), v.end ( ) ) ; // 2

Uusia toimintoja assosiatiiviseen taulukkoon lisäämiseen ei-toistuvalla avaimella

For std::mapja std::unordered_mapkaksi uutta toimintoa on lisätty [52] .

#include <iostream> #sisällytä <kartta> luokkapari { _ julkinen : int arvo1 , arvo2 ; Pari () : arvo1 ( 0 ), arvo2 ( 0 ) {} eksplisiittinen pari ( int aArvo1 ) : arvo1 ( aArvo1 ), arvo2 ( 0 ) {} Pari ( int aArvo1 , int aArvo2 ) : arvo1 ( aArvo1 ), arvo2 ( aArvo2 ) {} }; int main () { std :: kartta < std :: merkkijono , Pari > m ; // C++11 m [ "a" ] = Pari ( 3 , 4 ); m . emplace ( "a" , 1 ); // Pari luodaan aina // C++17 m . insert_or_assign ( "a" , pari ( 3 , 4 )); m . try_emplace ( "a" , 1 ); // Pari luodaan tarvittaessa paluu 0 ; }

Uusia matemaattisia funktioita

Standardista poikkeavia matemaattisia funktioita on lisätty std-nimiavaruuteen: beta, , , , , , , , , , , , [53] [54] . Ei ole yhtään std:n (in ) ulkopuolella. cyl_bessel_i/j/kcyl_neumann[comp_]ellint_1/2/3expinthermite[assoc_]laguerre[assoc_]legendreriemann_zetasph_besselsph_legendresph_neumannmath.h

Ensimmäisestä virkkeestä (2010): "Toivomme, että tämän ehdotuksen hyväksyminen lähettää viestin eri tietotekniikan yhteisöille, että yleisestä uskomuksesta huolimatta C++ soveltuu hyvin myös heidän alalleen." Sitten häntä ei hyväksytty. Nyt suurilla kirjastojen toimittajilla ( Dinkumware , Boost , GCC ) on jo nämä ominaisuudet.

Lisätty myös GCD :n [55] ja LCM :n [56] laskelma, vaihteluvälin pienennysfunktio ( ) [57] , kolmiulotteinen hypotenuusa . clamphypot(x, y, z)

Tiedostojärjestelmäkirjasto

Tiedostojärjestelmäkirjaston boost::filesystemavulla voit: [58]

  • tiedostonimien automaattinen kansainvälistyminen käyttöjärjestelmän ominaisuuksista riippuen. Kirjasto piilottaa koodauksen, jossa se toimii, ja muuntaa itse nimet halutuiksi - ainakin maa-asetuksiksi määritetyiksi yksitavuisiksi ja erilaisiksi Unicode-varianteiksi;
  • hakemiston läpikulku (mukaan lukien rekursiivinen);
  • tiedostotyyppien määrittely (tavallinen, hakemisto , socket ...);
  • tiedoston polun jakaminen osiin: asema, hakemisto, nimi ja tunniste;
  • hakemistojen luominen, tiedostojen kopioiminen, hakemistojen ja tiedostojen poistaminen (mukaan lukien rekursiiviset);
  • nimien hankkiminen väliaikaisille tiedostoille .

Muuttujatyypit

Oli luokka , joka pystyi sisältämään kaiken tyyppistä dataa [59] [60] . Toteutuksia tarvitaan sovittamaan pieniä esineitä varaamatta muistia. Toiminto vaatii tarkan tyypin vastaavuuden, eikä se anna mitään, jos se on . std::anyanyany_castany_cast<double>int

std :: cout << std :: boolalpha ; std :: mikä tahansa a = 1 ; std :: cout << a . tyyppi (). nimi () << ": " << std :: mikä tahansa_cast < int > ( a ) << std :: endl ; a = 3,14 ; std :: cout << a . tyyppi (). nimi () << ":" << std :: mikä tahansa_cast < double > ( a ) << std :: endl ; a = tosi ; std :: cout << a . tyyppi (). nimi () << ":" << std :: any_cast < bool > ( a ) << std :: endl ; // i: 1 // d: 3,14 // b: totta

On myös yksinkertaisempia std::variant<int, bool, double>ja std::optional<T>.

Matalan tason luku-tekstimuunnosfunktiot

Tunnettu C++:n haittapuoli: lukujen matalan tason muuntamiseen tekstiksi ilman muistivarausta sinun on suoritettava raskas ja epäluotettava sprintf, ja sisäänrakennettu tekstin muunnos C:llä jätetyksi numeroksi on melko epäluotettavaa.

Nyt on sisäänrakennetut paikallisesta riippumattomat supernopeudet from_chars[61] ja to_chars[62] . Ne on suunniteltu siten, että ne eivät vaadi (eivätkä tuota) sulkevaa nollaa ja voivat toimia esimerkiksi string_view. Rajoitteidensa ja paikallisen riippumattomuutensa vuoksi ne on ensisijaisesti tarkoitettu JSON- ja XML -tiedostoille , joissa tarvitaan valtavaa nopeutta.

Uusi tyyppi polymorphic_allocator

STL-tietorakenteet ( merkkijonot , vektorit jne.) sisältävät malliparametrin - muistin varaajan. Tämä allokaattori toimii yleisenä ohjelmointikonseptina , ei oliopohjaisena käyttöliittymänä: muistin varaaminen kasaan ja pooliin johtaa erilaisiin yhteensopimattomiin tyyppeihin. Luokka  on tavallinen aloitus harvinaiselle tehtävälle: varaa muistia joko kasaan tai pooliin tietyistä ehdoista riippuen. polymorphic_allocator

Se ei sinänsä  ole käyttöliittymä, mutta se liittyy käyttöliittymään . polymorphic_allocatormemory_resource

Uusi malli std::invoke

Mahdollistaa funktioiden, objektien johdonmukaisen kutsumisen operaattorilla () (funktiot ) ja lambda-objektien [63] . Lisätty myös toimintoja , , . is_invocableis_invocable_rinvoke_result

STL-algoritmien rinnakkaisversiot

69: lle algoritmille ja rinnakkaisversioille on keksitty [64] [65] [66] . <algorithm><numeric><memory>

Katso myös

Linkit

  • Standardiluonnos, N4659 , päivätty 21.3.2017

Muistiinpanot

  1. ISO/IEC 14882:2017 . Haettu 4. joulukuuta 2017. Arkistoitu alkuperäisestä 17. toukokuuta 2013.
  2. Viimeaikaiset virstanpylväät: C++17 on lähes täydellinen, toinen kierros TSe:tä on nyt kehitteillä . Haettu 28. maaliskuuta 2016. Arkistoitu alkuperäisestä 8. syyskuuta 2020.
  3. N3981: Trigrafien poistaminen??! (Richard Smith) (6. toukokuuta 2014). Haettu 28. maaliskuuta 2016. Arkistoitu alkuperäisestä 9. heinäkuuta 2018.
  4. IBM:n kommentti Trigraph-haitalliseen tulevaisuuteen valmistautumisesta C++17:ssä Arkistoitu 11. syyskuuta 2018 Wayback Machinessa , IBM paperi N4210, 10.10.2014.
  5. Poista vanhentunut rekisteriavainsanan käyttö . Haettu 20. elokuuta 2018. Arkistoitu alkuperäisestä 14. syyskuuta 2017.
  6. Poista vanhentunut operaattori++(bool) . Haettu 20. elokuuta 2018. Arkistoitu alkuperäisestä 11. syyskuuta 2017.
  7. Vanhentuneiden poikkeusmääritysten poistaminen C++17:stä . Haettu 20. elokuuta 2018. Arkistoitu alkuperäisestä 13. syyskuuta 2017.
  8. N4190: Auto_ptr, random_shuffle(), ja vanhojen <funktionaalisten> asioiden poistaminen (Stephan T. Lavavej) . Haettu 28. maaliskuuta 2016. Arkistoitu alkuperäisestä 20. lokakuuta 2017.
  9. 1 2 3 Päivitykset matkaraporttiini . Käyttöpäivä: 28. maaliskuuta 2016. Arkistoitu alkuperäisestä 19. maaliskuuta 2015.
  10. Poista vanhentuneet iostreams-aliakset . Haettu 20. elokuuta 2018. Arkistoitu alkuperäisestä 22. elokuuta 2017.
  11. Alokaattorituen poistaminen std::funktiosta (versio 1) . Haettu 20. elokuuta 2018. Arkistoitu alkuperäisestä 17. syyskuuta 2017.
  12. Vestigiaalikirjaston osien poistaminen käytöstä C++17:ssä . Haettu 20. elokuuta 2018. Arkistoitu alkuperäisestä 13. syyskuuta 2017.
  13. Poistetaan käytöstä <codecvt> . Haettu 20. elokuuta 2018. Arkistoitu alkuperäisestä 16. syyskuuta 2017.
  14. Ehdotettu ratkaisu CA 14:lle (shared_ptr use_count/unique) . Haettu 20. elokuuta 2018. Arkistoitu alkuperäisestä 7. heinäkuuta 2017.
  15. Ratkaiseminen GB 55, US 84, US 85, US 86 . Haettu 20. elokuuta 2018. Arkistoitu alkuperäisestä 5. heinäkuuta 2017.
  16. N4259: Sana sanalle std::uncaught_exceptions (Herb Sutter) . Haettu 28. maaliskuuta 2016. Arkistoitu alkuperäisestä 29. marraskuuta 2014.
  17. 1 2 3 4 5 C++17:lle otetut uudet ydinkielipaperit . Haettu 28. maaliskuuta 2016. Arkistoitu alkuperäisestä 27. huhtikuuta 2015.
  18. Lähde . Haettu 31. toukokuuta 2022. Arkistoitu alkuperäisestä 16. marraskuuta 2017.
  19. C++17:n tulisi viitata C11:een C99:n sijaan . Haettu 20. elokuuta 2018. Arkistoitu alkuperäisestä 13. syyskuuta 2017.
  20. N3922: Uudet säännöt automaattiselle vähennykselle aaltosulkujen aloituslistasta (James Dennett) . Haettu 28. maaliskuuta 2016. Arkistoitu alkuperäisestä 10. elokuuta 2015.
  21. Tee poikkeusmäärityksistä osa tyyppijärjestelmää . Haettu 20. elokuuta 2018. Arkistoitu alkuperäisestä 12. syyskuuta 2017.
  22. Dynaaminen muistin varaus ylikohdistettua dataa varten . Haettu 20. elokuuta 2018. Arkistoitu alkuperäisestä 8. syyskuuta 2017.
  23. [ http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0145r3.pdf Refining Expression Evaluation Order for Idiomatic C++] . Haettu 23. elokuuta 2018. Arkistoitu alkuperäisestä 26. elokuuta 2018.
  24. N4268: Salli jatkuva arviointi kaikille ei-tyyppisille mallipohjaargumenteille (Richard Smith) . Haettu 28. maaliskuuta 2016. Arkistoitu alkuperäisestä 12. maaliskuuta 2016.
  25. Aluepohjaisen silmukan yleistäminen . Haettu 23. elokuuta 2018. Arkistoitu alkuperäisestä 5. lokakuuta 2017.
  26. 1 2 Uudet standardikirjastopaperit käyttöön C++17:ssä . Haettu 28. maaliskuuta 2016. Arkistoitu alkuperäisestä 29. marraskuuta 2014.
  27. N4284: Jatkuvat iteraattorit (Jens Maurer) . Haettu 28. maaliskuuta 2016. Arkistoitu alkuperäisestä 29. marraskuuta 2014.
  28. N4267: U8-merkkisten literaalien lisääminen (Richard Smith) . Haettu 28. maaliskuuta 2016. Arkistoitu alkuperäisestä 28. lokakuuta 2015.
  29. Estä tilapäisesti muisti_tilaus_kulutus . Haettu 20. elokuuta 2018. Arkistoitu alkuperäisestä 16. tammikuuta 2018.
  30. Muistin_tilauksen_kulutuksen tarkoitus C++11:ssä . Haettu 15. elokuuta 2019. Arkistoitu alkuperäisestä 11. marraskuuta 2019.
  31. N3928: Static_assert, v2:n laajentaminen (Walter E. Brown) . Haettu 28. maaliskuuta 2016. Arkistoitu alkuperäisestä 11. elokuuta 2015.
  32. Näin ollen PVS-Studion kirjoittajat valittivat usein virheestä: ohjelmoija clear()kirjoitti empty().
  33. N4051: Salli tyypin nimi mallipohjan parametrissa (Richard Smith) . Haettu 28. maaliskuuta 2016. Arkistoitu alkuperäisestä 11. elokuuta 2015.
  34. Strukturoitu sitova ilmoitus (C++17 lähtien) Arkistoitu 8. syyskuuta 2020 Wayback Machineen en.cppreference.com
  35. N4230: Sisäkkäisen nimitilan määritelmä (Robert Kawulak, Andrew Tomazos) . Haettu 28. maaliskuuta 2016. Arkistoitu alkuperäisestä 3. elokuuta 2015.
  36. N4266: Attribuutit nimiavaruuksille ja luetteloijille (Richard Smith) . Käyttöpäivä: 28. maaliskuuta 2016. Arkistoitu alkuperäisestä 6. maaliskuuta 2016.
  37. constexpr jos: Hieman erilainen syntaksi . Haettu 20. elokuuta 2018. Arkistoitu alkuperäisestä 7. lokakuuta 2017.
  38. N4295: Taittolausekkeet (Andrew Sutton, Richard Smith) . Haettu 28. maaliskuuta 2016. Arkistoitu alkuperäisestä 4. huhtikuuta 2015.
  39. Heksadesimaaliset kelluvat literaalit C++:lle . Haettu 12. kesäkuuta 2019. Arkistoitu alkuperäisestä 22. elokuuta 2017.
  40. Valintalausekkeet alustuksella . Haettu 12. kesäkuuta 2019. Arkistoitu alkuperäisestä 6. lokakuuta 2017.
  41. Ei-tyyppisten mallien parametrien ilmoittaminen automaattisella . Haettu 7. elokuuta 2020. Arkistoitu alkuperäisestä 16. syyskuuta 2017.
  42. *tämän lambdakaappaus arvolla [=,*this ] . Haettu 7. elokuuta 2020. Arkistoitu alkuperäisestä 22. elokuuta 2017.
  43. Rakennussäännöt enum-luokan arvoille . Haettu 7. elokuuta 2020. Arkistoitu alkuperäisestä 9. joulukuuta 2017.
  44. C++17:n tulisi viitata C11:een C99:n sijaan . Haettu 18. joulukuuta 2016. Arkistoitu alkuperäisestä 13. marraskuuta 2016.
  45. N4280: Ei-jäsenkoko() ja enemmän (Riccardo Marcangelo) . Käyttöpäivä: 28. maaliskuuta 2016. Arkistoitu alkuperäisestä 9. maaliskuuta 2015.
  46. Sanamuoto bool_constantille, versio 1 . Haettu 1. tammikuuta 2020. Arkistoitu alkuperäisestä 14. lokakuuta 2017.
  47. Arkistoitu kopio . Haettu 1. tammikuuta 2020. Arkistoitu alkuperäisestä 28. elokuuta 2017.
  48. Arkistoitu kopio . Haettu 1. tammikuuta 2020. Arkistoitu alkuperäisestä 10. lokakuuta 2017.
  49. Arkistoitu kopio . Haettu 1. tammikuuta 2020. Arkistoitu alkuperäisestä 5. heinäkuuta 2017.
  50. P0154R1 constexpr std::hardware_{konstruktiivinen,tuhoisa}_interference_size .
  51. std::shared_mutex - cppreference.com . Haettu 30. elokuuta 2019. Arkistoitu alkuperäisestä 30. elokuuta 2019.
  52. Parannettu lisäysliittymä std::{unordered_,}kartalle (tarkistettu) . Haettu 28. maaliskuuta 2016. Arkistoitu alkuperäisestä 27. huhtikuuta 2015.
  53. Arkistoitu kopio . Haettu 20. elokuuta 2019. Arkistoitu alkuperäisestä 17. syyskuuta 2019.
  54. Matemaattiset erikoisfunktiot C++17:lle, v5 . Haettu 28. maaliskuuta 2016. Arkistoitu alkuperäisestä 5. huhtikuuta 2016.
  55. std::gcd - cppreference.com . Haettu 30. elokuuta 2019. Arkistoitu alkuperäisestä 28. maaliskuuta 2019.
  56. std::lcm - cppreference.com . Haettu 30. elokuuta 2019. Arkistoitu alkuperäisestä 28. maaliskuuta 2019.
  57. std::clamp - cppreference.com . Haettu 30. elokuuta 2019. Arkistoitu alkuperäisestä 30. elokuuta 2019.
  58. Tiedostojärjestelmän kirjastoehdotus (Beman Dawes) . Haettu 28. maaliskuuta 2016. Arkistoitu alkuperäisestä 20. heinäkuuta 2016.
  59. C++ Extensions for Library Fundamentals, versio 2, työluonnos . Haettu 30. elokuuta 2019. Arkistoitu alkuperäisestä 25. elokuuta 2019.
  60. std::any - cppreference.com . Haettu 30. elokuuta 2019. Arkistoitu alkuperäisestä 30. elokuuta 2019.
  61. std::from_chars - cppreference.com . Haettu 30. elokuuta 2019. Arkistoitu alkuperäisestä 30. elokuuta 2019.
  62. std::to_chars - cppreference.com . Haettu 30. elokuuta 2019. Arkistoitu alkuperäisestä 30. elokuuta 2019.
  63. Ehdotus kutsufunktiomallin lisäämiseksi (versio 1) . Haettu 1. tammikuuta 2020. Arkistoitu alkuperäisestä 6. lokakuuta 2017.
  64. Rinnakkaislaajennukset - cppreference.com . Haettu 5. helmikuuta 2021. Arkistoitu alkuperäisestä 12. marraskuuta 2020.
  65. Parallelism TS tulisi standardoida . Haettu 28. maaliskuuta 2016. Arkistoitu alkuperäisestä 5. huhtikuuta 2016.
  66. C++17-rinnakkaisalgoritmien käyttö paremman suorituskyvyn saavuttamiseksi | C++ Team -blogi . Haettu 5. helmikuuta 2021. Arkistoitu alkuperäisestä 24. tammikuuta 2021.