C++20

C++20 on C++-ohjelmointikielen ISO-standardiversio ISO/IEC 14882:2020, jonka kehitys alkoi C++17-standardin valmistumisen jälkeen. Standardiversio äänestettiin valmiiksi 15. helmikuuta 2020 ja hyväksytyksi ISO:n äänestyksessä syyskuussa. Standardiversio on julkaistu joulukuussa 2020. Edellinen standardiversio on ISO/IEC 14882:2017 C++17. Seuraava kehitettävä versio tulee olemaan C++23. == Kehityskohdat == Version kehityskohtia ovat muun muassa: * moduulit * rinnakkaisuuden jatkokehitys ** uusi synkronointikirjasto ** latch ja barrier luokat * concepts * ranges * coroutines * lambda-operaattoreiden käytön rajoitteiden vähentäminen `decltype` -yhteydessä ** `[=, this]` -kaappaus * kolmisuuntainen vertailu nk. avaruusalusoperaattorilla `<=>` * `volatile`-tuen merkintä suurelta osin vanhentuneeksi * `std::span` * ominaisuustestimakroja esikääntäjälle * bittioperaatioita * `char8_t` lisäys, `char16_t` ja `char32_t` muutokset (`u"foo"` ja `U"foo"`) Unicode-tukeen * vanhentuneeksi merkittyjen ominaisuuksien poistoja Haskell-kielen tyyppinen konsepti-ominaisuus, ranges-kirjasto sekä `std::future` odotetaan olevan myös kehityskohteina. Bjarne Stroustrup julkaisi työryhmälle paperin nimellä Remember the Vasa! viitaten Vasa-laivaan, jossa hän muistutti perusasioiden tärkeydestä ominaisuuksien määrän sijaan. Stroustrup on sanonut C++20-standardista sen olevan ”kolmas merkittävä standardi” (kuudesta standardista), jossa merkittävä tarkoittaa sen ”muuttavan ihmisten ajattelutapaa”. Merkittäviksi kohdiksi mainitaan: * concepts * moduulit * coroutines Moduulien käyttö voi mahdollistaa esikääntäjästä luopumisen. === Lykättyjä tai hylättyjä ominaisuuksia === * contracts on lykätty versioon C++23/C++26. * verkko-ohjelmointituen laajennukset (ISO/IEC TS 19216:2018) * reflektio * transaktiomuistin tuki Standardia on kuitenkin myös kritisoitu päätöksistä säilyttää yhteensopivuus ja haluttomuudesta rikkoa ABI-yhteensopivuus. ABI:n muutoksilla pyrittäisiin saavuttamaan parempaa suorituskykyä. == std::format == Standardikirjaston lisäys `std::format` on uusi vaihtoehto merkkijonojen muotoiluun, jonka tavoitteena on tarjota sama joustavuus kuin `printf`-sarjan funktioilla. Esimerkki: string message = format("The answer is {}.", 42); == Concepts == ISO:n tekninen määrittely: ISO/IEC TS 19217:2015 GCC-kääntäjän versiossa 6 on tukea ominaisuudelle. Standardimallikirjasto sisältää ominaisuutta tukevia määrittelyitä. Concepts on laajennus template-malleihin, jotka voivat toimia rajoitteina sallituille argumenteille tai parametreille. Constraint-rajoitteella voidaan valita ylikuormitukset ja erikoistumiset. Concepts toimii nimettynä joukkona rajoitteita, jotka arvioidaan käännösaikana. Tavoitteena on semanttisen tarkistuksen lisääminen syntaksitarkistuksen lisänä. Ominaisuuden on sanottu olevan puuttuva ominaisuus geneerisen ohjelmoinnin haittapuolien eliminoimiseksi. Kielen nimettyjä vaatimuksia voidaan esittää Concepts-kirjaston avulla. Esimerkiksi `std::hash`-tuen vaatimuskonsepti `Hashable` voidaan ilmaista: template concept Hashable = requires(T a) { { std::hash{}(a) } -> std::convertible_to; }; == Ranges == Eric Nieblerin esimerkkitoteutus on julkaistu osana ehdotusta ominaisuuden lisäämiseksi C++ standardiin ja on myöhemmin hyväksytty standardiin `std::ranges`-kirjastoksi. Kirjasto rakentuu Concepts-kirjaston ominaisuuksille. Toteutus on koottava abstraktiokerros iteraattoreiden päällä. Kirjasto tukee Haskell-kielen tapaan laiskaa arviointia, jossa ääretöntä määrää tukevasta toiminnosta suoritetaan vain tarvittava osa. Esimerkiksi kokonaislukujoukosta [1, ..] voidaan valita viisi numeroa ja tulostaa ne seuraavasti: auto num = view::take(view::ints(1), 5); ranges::for_each(num, [](int i){ std::cout << i << " "; }); Esimerkki (`std::views` on lyhenne `std::ranges::views` nimiavaruudelle): std::vector ints{0,1,2,3,4,5}; auto even = [](int i){ return 0 == i % 2; }; auto square = [](int i) { return i * i; }; for (int i : ints | std::views::filter(even) | std::views::transform(square)) { std::cout << i << ' '; } .. joka tulostaa annettujen arvojen joukosta (0..5) parillisten numeroiden (0, 2, 4) neliöt seuraavasti: 0 4 16 == Coroutines == Coroutines on ylemmän tason kielien kuten Simulan ominaisuus, joka toimii vaihtoehtona aliohjelmille (alifunktioille): rutiinit ovat pinottomia. Coroutines on tarkoitettu tilanteisiin, jossa eri funktiot vaihtavat suoritusvuoroaan jatkaen aiemmasta tilasta. Coroutines sallii funktion suorittamisen pysäyttämisen ja jatkamisen ja lisää kolme uutta operaattoria: * `co_await`, pysäyttää väliaikaisesti suorituksen palauttamatta arvoa kutsujalle * `co_yield`, pysäyttää väliaikaisesti ja palauttaa arvon kutsujalle * `co_return`, lopettaa suorituksen ja palauttaa arvon. Uudet operaattorit mahdollistavat asynkronisen suorituksen, generaattorit ja laiskat funktiot. Esimerkki: generator iota(int n = 0) { while(true) co_yield n++; } Boost-kirjastossa on esimerkkitoteutus C++:lle. Coroutines on hyväksytty mukaan C++20:een. == Moduulit == Moduulit (modules) on vaihtoehtoinen tapa otsikkotiedostoille, joka muun muassa mahdollistaa makrojen eriyttämisen. Aiemmin ohjelmoijille on ollut mahdollista käyttää kolmea nimettyä kapselointia: # muuttujanimi # funktionimi # luokkanimi Moduulit lisäävät neljännen nimetyn kapseloinnin, joka sisältää kaikki kolme aikaisempaa yhdessä. Moduulit on hyväksytty mukaan C++20:een. Epävirallinen tuki toiminnolle on ollut aiemmin Clang-kääntäjässä. Esimerkki: // moduulissa: // helloworld.cpp export module helloworld; // module declaration import ; // import declaration export void hello() { // export declaration std::cout << "Hello world! "; } // moduulin käyttö: // main.cpp import helloworld; // import declaration int main() { hello(); } == Lähteet == == Aiheesta muualla == * Standardivedokset Luokka:C++