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<typename T>
concept Hashable = requires(T a) {
    { std::hash<T>{}(a) } -> std::convertible_to<std::size_t>;
};

 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<int> 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<int> 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 <iostream>;         // import declaration

export void hello() {      // export declaration
    std::cout << "Hello world!\n";
}

// moduulin käyttö:
// main.cpp
import helloworld;  // import declaration

int main() {
    hello();
}

 Lähteet 

 Aiheesta muualla 
 Standardivedokset 

Luokka:C++