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 versio on C++23.
Version kehityskohtia ovat muun muassa:
decltype -yhteydessä
[=, this] -kaappaus<=>volatile-tuen merkintä suurelta osin vanhentuneeksistd::spanchar8_t lisäys, char16_t ja char32_t muutokset (u"foo" ja U"foo") Unicode-tukeenHaskell-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:
Moduulien käyttö voi mahdollistaa esikääntäjästä luopumisen.
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ä.
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);
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>;
};
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 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 kutsujalleco_yield, pysäyttää väliaikaisesti ja palauttaa arvon kutsujalleco_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 (modules) on vaihtoehtoinen tapa otsikkotiedostoille, joka muun muassa mahdollistaa makrojen eriyttämisen. Aiemmin ohjelmoijille on ollut mahdollista käyttää kolmea nimettyä kapselointia:
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();
}