C++20
Aktuální verze stránky ještě nebyla zkontrolována zkušenými přispěvateli a může se výrazně lišit od
verze recenzované 17. ledna 2022; kontroly vyžadují
135 úprav .
C++20 je název normy ISO /IEC pro programovací jazyk C++ . Specifikace byla zveřejněna v prosinci 2020 [1] .
Výbor pro standardy C++ začal plánovat C++20 v červenci 2017 [2] . C++20 je nástupcem C++17 .
Konstanta se zvýšila na .
__cplusplus202002L
Zakázáno a odstraněno
Operace s volatile jsou zakázány
Modifikátor je samozřejmě závislý na stroji - pro komunikaci s vybavením. Není tedy jasné, jaká je sémantika té či oné operace a kolik paměťových přístupů bude. Pro synchronizaci mezi vlákny je lepší použít .
volatileatomic
Následující operace s -proměnnými jsou zakázány [3] :
volatile
- operace , ;++--
- operace a další (operace jsou v C++23 zakázány );+=&=, |=, ^=
- přiřazovací řetězce;
- funkce, parametry a návratové hodnoty s modifikátorem volatile;
- všechny funkce STL spojené s volatile, kromě některých jako remove_volatile;
atomicByly přidány další funkce, které kompenzují to, co bylo zakázáno
.
Byla odstraněna inicializace agregace, když existuje vlastní konstruktor
V předchozích standardech byla agregovaná inicializace povolena, pokud byl konstruktor označen jako nebo , což uživatele uvedlo v omyl: objekt je inicializován obcházením konstruktoru.
defaultdelete
struktura X {
int a = 0 ; x () = výchozí ;
};
X x { 5 }; // C++17: OK // C++20: žádný odpovídající konstruktor pro inicializaci 'X'
Odstraněny zákazy z C++17
Odstraněny vzácné standardní funkce knihovny zakázané v C++ 17: [4] [5] [6]
- allocator<void> - se ukázalo jako nevyžádané;
- některé funkce allocator jsou duplikovány šablonou allocator_traits;
- raw_storage_iterator - nevolá konstruktory, a proto je aplikace omezená;
- get_temporary_buffer - má nezřejmá úskalí;
- is_literal_type - nepoužitelný pro generický kód;
- shared_ptr::unique() - kvůli nespolehlivosti ve vícevláknovém prostředí; pokud to opravdu potřebujete, použijte ;use_count
- result_of - nahrazeno invoke_result;
- uncaught_exception() - nahrazeno uncaught_exceptions.
- <ccomplex>, <ciso646>, <cstdalign>, <cstdbool>, <ctgmath> — nemají v C++ žádný význam. a další ponechány pro kompatibilitu s C.<complex.h>
Tato poznámka byla odstraněna z jazyka , který byl v C++11 nahrazen jazykem . Pokud potřebujete kompatibilitu s C++03, musíte napsat něco jako
throw()noexcept
#if __cplusplus < 201103L
#define noexcept throw() #endif
Vlevo, odjet:
- codecvt - ve skutečnosti to fungovalo velmi špatně, komise vyzvala k využití specializovaných knihoven.
- iterator - je jednodušší psát iterátory od začátku, než na nich stavět.
- proudy - není jasné, co je na oplátku.char*
- implicitní vytvoření operace "přiřadit", pokud existuje konstruktor kopírování a destruktor (a také konstruktor kopírování, pokud existuje přiřazení a destruktor) - knihovna stále spoléhá na toto chování.
Další zákazy z jazyka
- Implicitní zachycení ve funkcích lambda - kvůli nejasné sémantice. Existuje pro snímání pomocí ukazatele a snímání pomocí kopie.*this[](){ std::cout << myField; }[this](){ std::cout << myField; }[*this](){ std::cout << myField; }
- Operace "čárka" v indexech pro libovolné a, b a c je způsobena nezřejmým chováním a touhou vytvořit novou syntaxi pro vícerozměrná pole [7] . Pokud to opravdu potřebujete, napište .a[b,c]a[(b,c)]
- Implicitní konverze na výčtový typ – pro předvídatelnější chování nové operace hvězdné lodi ( , srovnání se třemi hodnotami).<=>
- Porovnání dvou polí - pro předvídatelnější chování nové operace "hvězdná loď" ( , třímístné srovnání). Alespoň jeden musí být převeden na ukazatel.<=>
Další zákazy z knihovny
- is_pod - namísto složitého konceptu „ jednoduché datové struktury “ je lepší použít specifické vlastnosti typu: je triviálně postaven, triviálně zničen atd. Pokud je to velmi nutné (např. přenos dat mezi pluginy ), je ekvivalentní k .is_trivial && is_standard_layout
- std::rel_ops Nová operace Starship to dělá lépe.
- atomové schopnosti - není jasné, jak pracovat s ukazatelem, atomicky nebo ne. Je lepší to definovat pomocí typového systému, .shared_ptratomic<shared_ptr>
- string::capacity() - nyní rozhodl, že nebude snižovat kapacitu.reserve
- filesystem::u8path — se nyní liší od .u8stringstring
- ATOMIC_FLAG_INIT, atomic_init, ATOMIC_VAR_INIT — nyní to dělá konstruktor šablon .atomic
Jazyk
Drobné změny
- Přidán nepodepsaný typ char8_t schopný obsahovat jednotky UTF-8 .
- using EnumClass, což umožňuje, aby byl kód na klíčových místech méně nepřehledný.
- Dodatečná inicializace v pro podle objektu: [8] . Pokud je vrácený objekt dočasný , jeho životnost se prodlouží na celý cyklus, ale ostatní dočasné objekty budou bezpečně odstraněny, a pokud je f() pravdivé, zápis je chybný.for (T thing = f(); auto& x : thing.items())items()for (auto& x : f().items())
Moduly
Direktiva kompilátoru #includebyla svého času pohodlným mechanismem C, což byl ve skutečnosti multiplatformní assembler, který „parazitoval“ na nástrojích assembleru – linkeru a knihovníku. Proto důležitá vlastnost kompilátorů C - byly první, které se po assembleru objevily na nových platformách. S rozšiřováním projektů se však doba jejich kompilace kvadraticky prodloužila: zvýšil se jak počet překladových jednotek , tak počet k nim připojených hlaviček. Modulový mechanismus je již od dob C++11 dlouhodobým předmětem sporů.
Vstoupilo do C++20 takto [9] :
// helloworld.cpp
exportní modul helloworld ; // import deklarace modulu < iostream > ; // deklarace importu export void hello () { // deklarace exportu std :: cout << "Ahoj světe! \n " ;
}
Coroutines
Korutina je speciální bezzásobníková funkce, která může pozastavit své provádění, zatímco je vykonávána jiná funkce [10] . Stav korutiny je uložen v paměti haldy (pokud se optimalizátoru nepodařilo alokaci zbavit). Vypadá jako běžná funkce, ale obsahuje speciální klíčová slova coroutine .
co_*
task <> tcp_echo_server () {
char data [ 1024 ];
pro (;;) {
size_t n = co_await socket . async_read_some ( buffer ( data ));
co_await async_write ( socket , buffer ( data , n ));
}
}
Fyzicky je coroutine funkcí, která vrací čerstvě vytvořený objekt slibu. Pokaždé, když uživatel něco udělá s objektem slibu, řízení se přenese do kódu korutiny. V knihovně je k dispozici několik standardních příslibů - například poskytuje líné hodnocení .
lazy<T>
název_typu je prohlášen za redundantní, kde je povolen pouze typ
Na některých místech šablon už slovo typename(vysvětlující, že jde o typ a ne o funkci) není vyžadováno [11] . Mezi tato místa patří…
Object::Thing
- zadejte po -newauto x = new Object::Thing;
- zadejte -usingusing Thing = Object::Thing;
- konečný návratový typ ;auto f() -> Object::Thing
- výchozí typ v šablonětemplate<class T = Object::Thing> T f();
- zadejte static_cast , const_cast , reinterpret_cast , dynamic_cast —auto x = static_cast<Object::Thing>(y);
- typ proměnné/funkce ve jmenném prostoru (včetně globálního) nebo třídy —Object::Thing variable;
- typ parametru funkce/šablony, pokud existuje identifikátor (kromě výrazů souvisejících s výpočtem výchozí hodnoty parametru) —void func(Object::Thing x);
šablona < třída T > T :: Rf ( ); // OK nyní, zadejte šablonu globálního jmenného prostoru < class T > void f ( T :: R ); // Potřebujete název typu, bez něj je to pokus o vytvoření proměnné void inicializované pomocí šablony T::R < class T > struct S {
pomocí Ptr = PtrTraits < T >:: Ptr ; // Nyní OK, zadejte pomocí T :: R f ( T :: P p ) { // Nyní OK, zadejte class return static_cast < T :: R > ( p ); // Nyní OK, static_cast }
auto g () -> S < T *>:: Ptr ; // OK nyní, konečný návratový typ };
template < typename T > void f () {
void ( * pf )( T :: X ); // Zůstává v pořádku, proměnná typu void* inicializována pomocí T::X void g ( T :: X ); // Potřebujete název typu, bez něj je to pokus o vytvoření proměnné void inicializované pomocí T::X }
Výpočet velikosti pole v new
Velikost pole v operátoru new se nyní automaticky odečítá [12]
double a []{ 1 , 2 , 3 }; // Zůstává v pořádku double * p = new double []{ 1 , 2 , 3 }; // Teď OK
Nové atributy
- [[no_unique_address]] - proměnná bez dat nesmí zabírat místo a další proměnné mohou být uloženy v „otvorech“ proměnné s daty. Ale: proměnné stejného typu nemohou být nikdy na stejné adrese.
šablona < class Allocator > class Storage {
soukromé :
[[ no_unique_address ]] Allocator alloc ;
};
- [[nodiscard("причина")]] je rozšířením stejnojmenného atributu C++17. Označuje, že návratová hodnota funkce by neměla být ignorována, a vydává důvod.
class XmlReader { // čtečka typu XML stream public :
[[ nodiscard ( "Zkontrolujte výsledek nebo použijte requireTag" )]] bool getTag ( const char * name );
void requireTag ( const char * název ) {
if ( ! getTag ( name ))
throw std :: logic_error ( std :: string ( "requireTag: " ) + jméno + " nenalezeno" );
}
};
- [[likely]] / [[unlikely]] - všimněte si, pod kterými větvemi je nutné optimalizovat program pro co nejlepší práci větveného prediktoru . Tato technika je ve skutečnosti již implementována v některých kompilátorech, viz __builtin_expectnapříklad GCC.
if ( x > y ) [[ nepravděpodobné ]] {
std :: cout << "Zřídka se stává" << std :: endl ;
} jinde [[ pravděpodobné ]] {
std :: cout << "Často se stává" << std :: endl ;
}
Rozšířený constexpr
Constexpr umožňuje:
- volání virtuálních funkcí [13] ;
- volání destruktorů, které musí být také ;constexpr
- pracovat s union[14] ;
- práce s - blok intercept nedělá nic a vyvoláním výjimky v tomto kontextu, jako předtím, se funkce vypočítá během provádění [15] ;try
- použití a [16] ;dynamic_casttypeid
- new, s určitými omezeními [17] ;
- asmpokud není volána při kompilaci;
- neinicializované proměnné.
Teoreticky taková konstrukce umožní například vytvořit konstantní std::vector jednoduše ukázat na paměť odpovídajícího std::initializer_list a běžnou nekonstantní alokovanou dynamickou paměť.
Rozšířená volání funkce lambda v době kompilace - například můžete třídit std::tuple .
Klíčová slova consteval a constinit
kód constexpr není nutné volat při kompilaci a stačí jej zapsat tak, aby se řetězec constexpr přerušil v konstruktoru std::set a při spuštění došlo k inicializaci. Někdy je to nežádoucí - pokud se proměnná používá při inicializaci programu (známá nevýhoda C++ - nekontrolované pořadí inicializace souborů CPP), velká (například velká tabulka) nebo obtížně vypočítatelná (inicializace stejného tabulka, která má O (n²)). A programátoři mají jen sportovní zájem o převod kódu do kompilace. Aby byla zajištěna jistota, jsou použita dvě nová klíčová slova:
std::set<std::string_view> dic { "alpha", "bravo" };
- constevalve funkcích: vyžaduje, aby byla funkce provedena při kompilaci. Volání z kontextu, který není spustitelný během kompilace, není povoleno. V hlavičkách kompatibility se staršími kompilátory nahrazeno .constexpr
- constinitv proměnné: vyžaduje, aby byla proměnná vyhodnocena při kompilaci. Nahrazeno prázdným řetězcem v záhlaví kompatibility se staršími kompilátory.
consteval int sqr ( int n )
{ return n * n ; }
const auto res2 = sqr ( 5 ) ;
int main ()
{
int n ;
std :: cin >> n ;
std :: cout << sqr ( n ) << std :: endl ; // chyba, nevyčíslitelná při kompilaci }
explicitní (bool)
Klíčové slovo lze zapsat společně s booleovským konstantním výrazem: pokud je pravdivý, převod je možný pouze explicitně. Zjednodušuje metaprogramování, nahrazuje idiom SFINAE [18] .
explicit
// Bylo, std::forward vynecháno kvůli stručnosti
šablony < class T > struct Wrapper {
šablona < class U , std :: enable_if_t < std :: is_convertible_v < U , T >>* = nullptr >
Obálka ( U const & u ) : t_ ( u ) {}
šablona < class U , std :: enable_if_t <! std :: is_convertible_v < U , T >>* = nullptr >
explicitní obal ( U const & u ) : t_ ( u ) {}
Tt_ ; _
};
// Stala se
šablonou < class T > struct Wrapper { template < class U > explicit ( ! std :: is_convertible_v < U , T > ) Wrapper ( U const & u ) : t_ ( u ) {}
Tt_ ; _ };
Třímístné srovnání ("hvězdná loď")
Operace vám umožňuje porovnávat objekty pomocí jedné ze tří metod:
<=>
- Částečné pořadí : menší než, ekvivalentní, větší než, nesrovnatelné.
- Slabé pořadí : menší než, ekvivalent, větší než. Může se stát, že hodnota některého veřejného pole nebo funkce se může u ekvivalentních objektů lišit. Pojem „ekvivalent“ je tranzitivní.
- Silné (lineární) pořadí (menší než, rovno, větší než). Stejné objekty jsou rozlišitelné pouze podle adresy.
class PersonInFamilyStrom { // ... public :
std :: operátor částečného_objednávky <=> ( const PersonInFamilyTree & that ) const {
if ( this -> is_the_same_person_as ( that )) return limited_ording :: ekvivalent ;
if ( this -> is_transitive_child_of ( that )) return partial_ording :: less ;
if ( that . is_transitive_child_of ( * this )) return čiastočné_uspořádání :: větší ;
return částečné_uspořádání :: neuspořádané ;
}
};
Název "hvězdná loď" pochází ze staré hry Star Trek - tyto tři postavy znamenaly " Enterprise ".
Verze těla operace hvězdné lodi jednoduše porovnává všechna pole v pořadí deklarací. Operace "rovná se" tělu je také možná , také porovná všechna pole v pořadí deklarace a automaticky deklaruje operaci "nerovná se" [19] .
=default=default
Koncepty
Koncept - požadavky na parametry šablony, aby tato šablona dávala smysl. Po většinu životnosti C++ byl koncept popisován slovně, se složitými chybami ve známých a platných záhlavích, jako je STL, pokud programátor do konceptu nezapadal. Pokud programátor napíše šablonu sám, může omylem opustit koncept a neuvidí ho v testovacím programu, protože se zdá, že nejjednodušší typy mají mnoho výchozích funkcí, jako je kopírovací konstruktor, přiřazení a aritmetické operace.
int
šablona < classT > _
koncept bool RovnostPorovnatelné ( ) { návrat vyžaduje ( T a , Tb ) {
{ a == b } -> Boolean ; // Koncept znamenající typ, který se má převést na booleovský { a != b } -> booleovský ;
};
}
Řetězcové konstanty jako parametry šablony
Kompilace zpracování řetězců bylo snem C++ již dlouhou dobu a dalším krokem k němu jsou řetězcové konstanty v šablonách [20] . Zejména bych rád převedl regulární výrazy na bytecode již při kompilaci. Experimentální knihovny regulárních výrazů již zaznamenaly až 3000násobné zrychlení ve srovnání s std::regex .
šablona < auto & str >
void f () {
// str = char const (&)[7]
}
f < "foobar" > ();
Inicializace pojmenované struktury
Řádná inicializace struktur C je chybná, pokud se očekává expanze struktury nebo pokud může dojít k záměně dvou sousedních prvků. Nový standard přidal , který existoval v C po dlouhou dobu, ale nebyl formalizován v C++ [21] .
Point p { 10, 20 };Point p { .x=10, .y=20 };
Navíc vám tato konstrukce umožňuje inicializovat přesně tu možnost union, kterou potřebujete.
union FloatInt {
plovák jakoPloat ;
int32_t asInt ;
};
FloatInt x { . asInt = 42 };
Odstraněno ve srovnání s C:
- inicializace pojmenovaného pole — počínaje C++11, hranaté závorky na začátku výrazu označují funkci lambda.int arr[3] = {[1] = 5};
- deklarace mimo provoz - konflikty s autodestruktory C++: vytvořeno v jednom pořadí, zničeno v jiném?Point p { .y=20, .x=10 };
- pojmenovaná inicializace členů vnořené struktury - málo používanéstruct B b = {.a.x = 0};
- míchání pojmenované a řadové inicializace:Point p {.x = 1, 2};
Změny funkcí lambda
Funkce lambda se objevily v C++11 po jiných programovacích jazycích. Řeší několik problémů najednou: nahrazují preprocesor, pokud je nutné provést stejný kód na dvou místech funkce, a jeho umístění do samostatného objektu / funkce je časově náročné; posuňte text funkce blíže k požadovanému místu; vám umožní psát funkčním stylem. Pojmenováno po lambda kalkulu , jednom ze základů funkcionálního programování.
Explicitní zachycení objektu ve funkci lambda [=, this](){}a [=, *this](){}[22] . Jak bylo uvedeno výše, implicitní odposlech ve funkcích lambda byl zakázán.
this
Tradiční syntaxe šablony lambda namísto C++14 . Tato syntaxe je výhodnější, pokud potřebujete provést autotest nebo vypočítat nějaký odvozený typ [23] .
[](auto x)
// Bylo
auto f = []( auto vector ) {
using T = typename decltype ( vector ) :: value_type ;
...
};
// Stalo se
auto f = [] < typename T > ( std :: vector < T > vector ) {
...
};
Funkce lambda v nevyčíslitelných kontextech : podpisy, návratové typy, parametry šablony [24] [25] .
std :: prioritní_fronta <
int , // typ prvku std :: vector < int > , // typ kontejneru decltype ( []( int a , int b ) -> bool { // typ funkce porovnání prvků return a > b ;
}) > q ;
Aby tento kód fungoval, je potřeba ještě jedna změna – funkce lambda bez háčků má nyní výchozí konstruktor a operátor přiřazení [24] [26] . Všechny instance této pseudotřídy dělají totéž a neexistuje způsob, jak přinutit frontu dané priority k porovnání v jiném pořadí. Konstruktory kopírování a přesunutí byly původně ve všech funkcích lambda.
V seznamu zachycení funkce lambda je nyní možné ponechat operaci expanze proměnné části [24] [27] - dříve k tomu bylo nutné zahrnout objekt n-tice. Tato šablona například vrací funkci lambda, kterou lze v případě potřeby kdykoli zavolat – volá funkci foo () a již obsahuje kopie všech dat potřebných k volání.
// Byla
šablona < class ... Args >
auto delay_invoke_foo ( Args ... args ) {
return [ tup = std :: make_tuple ( std :: move ( args )...)]() -> decltype ( auto ) {
return std :: použít ([]( auto const & ... args ) -> decltype ( auto ) {
return foo ( args ...);
}, tup );
};
}
// Stala se
šablonou < class ... Args >
auto delay_invoke_foo ( Args ... args ) {
return [ args = std :: move ( args )...]() -> decltype ( auto ) {
return foo ( args ...);
};
}
Redakční změny
Nové implicitní podmínky přesunu
Vyjasněné podmínky, kdy je potřeba implicitně hýbat objektem, zejména při vyvolání výjimek: [28]
void f () {
Tx ; _
zkuste {
T y ;
zkuste { g ( x );}
chytit (...) {
pokud ( /*...*/ )
hodit x ; // se nepohne - x mimo blok try throw y ; // přesun - y uvnitř bloku try }
g ( y );
} catch (...) {
g ( x );
// g(y); // chyba
}
}
Čísla se znaménkem - dvojkový doplněk
Když byl jazyk C v plenkách, existovala „zoo“ různých strojů a vzdělávací stroj MIX , který vynalezl Donald Knuth , to odrážel - bajt mohl uložit 64 až 100 různých hodnot a formát čísel se znaménkem nebyla specifikována. Po více než čtyřicet let se usadili na 8bitovém bajtu a dvojkovém doplňku , především kvůli jednoduchosti a součinnosti , což bylo uvedeno ve standardu [29] .
Aritmetické přetečení v aritmetice bez znaménka je ekvivalentní operacím modulo při aritmetice se znaménkem - nedefinované chování .
Nový model paměti
Ústně ukončeno s C++17 , určeno pro PowerPC a ARM, formalizováno a vráceno k použití. Vyztužené [30] .
memory_order_consumememory_order_seq_cst
Knihovna
Drobné změny
- Nové verze týkající se polí [31] [32] .make_unique/make_shared
- atomic<shared_ptr<>>a .atomic<weak_ptr<>>
- atomic_ref<>, objekt, který umožňuje vyrobit cokoliv atomového [33] .
- std::erase, , zjednodušit metaprogramování [34] .std::erase_if
- map.contains[35] .
- Nová hlavička je standardním místem pro oznámení související s vývojem konkrétní standardní knihovny [36] . Prohlášení jsou implementována.<version>
- to_address — převod objektu podobného ukazateli na ukazatel [37] . již existuje, ale vyžaduje dereferenci, která se může stát nedefinovaným chováním .addressof
- Novinka #definepro testování funkčnosti kompilátoru a knihovny [38] . Standardy C++ jsou obrovské a ne všichni vývojáři kompilátorů je rychle začleňují do svých produktů. A některé – C++11 garbage collection – zůstávají útržky dodnes (2021), nejsou implementovány v žádném kompilátoru.
- Zjednodušené kari pomocí [39] .bind_front
- source_location - obal pro makra a podobná v C++.__FILE__
- Nový nadpis s matematickými konstantami [40] . Předtím i obvyklé π a e existovaly pouze jako rozšíření.<numbers>
Deklarace funkce constexpr
- std::pointer_traits[41] .
- xxx.empty()a některé další. Psaní se místo toho stalo standardní chybou C++ [42] [43] a je deklarováno .xxx.empty();xxx.clear();[[nodiscard]]
- <numeric>[44] .
- konstruktor-destruktory std::vector a std::string , důsledek relaxací constexpr. V době revize (květen 2020) to žádný kompilátor nepodporuje [45] .
Knihovna formátování
printf je příliš nízkoúrovňový, nebezpečný a nerozšiřitelný. Standardní funkce C++ umožňují pouze zřetězení řetězců, a proto jsou pro lokalizaci nepohodlné .
Proto C++20 zavedlo typově bezpečnější mechanismus formátování řetězců založený na Pythonu [46] .
char c = 120 ;
auto s1 = std :: formát ( "{:+06d}" , c ); // "+00120" auto s2 = std :: format ( "{:#06x}" , 0xa ); // "0x000a" auto s3 = std :: format ( "{:<06}" , -42 ); // "-42 " (0 je ignorováno kvůli zarovnání <)
Schopnosti:
- Stejný parametr lze naformátovat libovolněkrát různými způsoby.
- Střídání je možné vyměnit.
- Zarovnání vlevo, na střed a vpravo, libovolný znak.
- Ve výchozím nastavení jsou čísla, data a tak dále formátována lokálně neutrálně; pokud je potřeba lokalizace, nastaví se explicitně.
- Funguje prostřednictvím šablon, a proto se rozšiřuje na všechny typy.
- Závorky mohou být vynechány {{ }} .
Nevlastnící ukazatele na pole (rozpětí)
std::string_view se ukázal jako skvělý objekt a udělali to samé pro pole - std::span [47] . Zároveň může span změnit obsah paměti, na rozdíl od string_view .
void do_something ( std :: span < int > p ) {
std2 :: řazení ( p );
for ( int & v : p ) {
v += p [ 0 ];
}
}
// ...
std :: vector < int > v ;
udělat_něco ( v );
intdata [ 1024 ] ;
udělat_něco ( data );
boost :: kontejner :: small_vector < int , 32 > sm ;
udělat_něco ( sm );
Knihovna pro práci s bity <bit>
Knihovna pro práci se synchronizovanými "výstupními proudy" <syncstream>
Výstupní vlákno zpravidla zpracovává přístup z různých vláken provádění samo . Při vícevláknovém protokolování vyvstává úkol: shromáždit data (například řádek textu) do vyrovnávací paměti dostatečné délky a odeslat je do proudu v jedné operaci.
K tomu se používá jednoduchá třída, která je potomkem .
ostream
osyncstream { cout } << "Odpověď je " << 6 * 7 << endl ;
Veškerý výstup do podřízeného vlákna se odehrává v jediné operaci v destruktoru.
Knihovna rozsahů <rozsahy>
Komplexní knihovna se používá tam, kde je potřeba jednotný přístup, jako je std::vector a std::deque [48] .
Knihovna kalendářů a časových pásem v <chrono>
Komplexní knihovna pro kalendářní výpočty [49] .
auto d1 = 2018_y / mar / 27 ; _
auto d2 = 27_d / březen / 2018 ; _
auto d3 = březen / 27 / 2018 ;
rok_měsíc_den dnes = podlaha < dny > ( system_clock :: now ());
tvrdit ( d1 == d2 );
tvrdit ( d2 == d3 );
tvrdit ( d3 == dnes );
Písmeno j znamená join – to znamená, že když je objekt vlákna zničen, systém čeká na dokončení úlohy.
Kromě toho můžete pomocí knihovny požádat o zastavení vlákna.
stop_token
#include <vlákno>
#include <iostream>
pomocí jmenného prostoru std :: literals :: chrono_literals ;
void f ( std :: stop_token stop_token , int hodnota )
{
while ( ! stop_token . stop_requested ()) {
std :: cout << hodnota ++ << ' ' << std :: flush ;
std :: this_thread :: sleep_for ( 200ms ) ;
}
std :: cout << std :: endl ;
}
int main ()
{
std :: jvlákno vlákno ( f , 5 ); // vytiskne 5 6 7 8... po dobu přibližně 3 sekund std :: this_thread :: sleep_for ( 3 s );
// Destruktor jthread volá request_stop() a join().
}
Svodidla a šrouby
Bariéra je mezivláknový synchronizační mechanismus, který funguje takto: jakmile se n vláken shromáždí u bariéry , provede funkční objekt a uvolní je. Obvykle se používá pro pravidelnou koordinaci částečně paralelizovaných úloh: poté, co vlákna dokončí svůj podíl, koordinátor spustí a rozhodne, co dál.
Západka je zjednodušená jednorázová závora [50] .
Heterogenní vyhledávání v unordered_set / map
Hlavní účel: klíče úložiště jsou „těžké“ objekty (například string ), ale jako vyhledávací klíč jsou přijatelné i lehké: string_view a dokonce const char*. Je implementován velmi jednoduše: je přidána šablonová funkce find, která akceptuje jakýkoli typ, zatímco samotné heterogenní vyhledávání je zahrnuto typem markeru [51] . Jsou podporovány čtyři funkce: find, count, equal_range, include. C++23 očekává více funkcí, které podporují heterogenní vyhledávání, jako je mazání [52] .
is_transparent
Pro samovyvažovací vyhledávací stromy ( set / map ) implementované v C++14.
Tato funkce není ve výchozím nastavení povolena kvůli chybě: převod typu nemusí zachovat vztahy, na kterých kontejner pracuje. Například , ale . Hledání zlomkového čísla v tedy nepovede k tomu, co potřebujete [53] . Takže programátor sám musí povolit ty alternativní klíče, které se jistě hodí.
1.0 < 1.1static_cast<int>(1.0) == static_cast<int>(1.1)set<int>
struct string_hash {
pomocí is_transparent = void ;
[[ nodiscard ]] operátor size_t ()( const char * txt ) const {
return std :: hash < std :: string_view > {}( txt );
}
[[ nodiscard ]] operátor size_t ()( std :: string_view txt ) const {
return std :: hash < std :: string_view > {}( txt );
}
[[ nodiscard ]] operátor size_t ()( const std :: string & txt ) const {
return std :: hash < std :: string > {}( txt );
}
};
std :: unordered_map < std :: string , int , string_hash , std :: equal_to <>> m { { "Ahoj Super dlouhý řetězec" , 1 }, { "Další dlouhý řetězec" , 2 }, { "Toto nemůže spadat do Vyrovnávací paměť jednotného přihlášení" , 3 }
};
bool nalezen = m . obsahuje ( "Ahoj Super dlouhý řetězec" );
std :: cout << "Nalezeno: " << std :: boolalpha << nalezeno << '\n' ;
Implementováno jako experimentální knihovny
- Concurrency v2 [54] , včetně bloků úloh. Verze 1 je součástí C++17.
- Odraz v1 [55]
- Síť v1 [56]
Zanecháno pro budoucnost
- Smlouvy – existuje konkurenční nabídka
- Metatřídy
- Účinkující
- Vlastnosti
- Prodloužená budoucnost
Viz také
Poznámky
- ↑ ISO/IEC 14882:2020 (anglicky) . ISO . Staženo: 21. prosince 2020.
- ↑ Aktuální stav : Standardní C++ . Získáno 8. února 2019. Archivováno z originálu dne 8. září 2020.
- ↑ P1152R4: Ukončení podporyvolatile . Získáno 9. srpna 2022. Archivováno z originálu dne 9. srpna 2022. (neurčitý)
- ↑ Zavržení pozůstatkových knihovních částí v C++17 . Získáno 29. ledna 2021. Archivováno z originálu 13. září 2017. (neurčitý)
- ↑ Ukončení podpory <codecvt> . Získáno 29. ledna 2021. Archivováno z originálu 16. září 2017. (neurčitý)
- ↑ Navrhované rozlišení pro CA 14 (shared_ptr use_count/unique) . Získáno 29. ledna 2021. Archivováno z originálu dne 7. července 2017. (neurčitý)
- ↑ P1161R3: Odmítněte použití operátoru čárka ve výrazech pro indexování . www.open-std.org . Získáno 21. prosince 2020. Archivováno z originálu dne 9. listopadu 2020.
- ↑ Zpráva z cesty: Podzimní schůze ISO C++ standardů (Albuquerque) – Sutter's Mill . Staženo 8. února 2019. Archivováno z originálu 13. února 2019. (neurčitý)
- ↑ Moduly (od C++20) - cppreference.com . Získáno 2. února 2021. Archivováno z originálu dne 27. ledna 2021. (neurčitý)
- ↑ Coroutines (C++20) - cppreference.com . Získáno 3. února 2021. Archivováno z originálu dne 25. března 2021. (neurčitý)
- ↑ Pryč s typename! . Získáno 13. srpna 2020. Archivováno z originálu dne 22. dubna 2018. (neurčitý)
- ↑ Archivovaná kopie . Získáno 14. srpna 2020. Archivováno z originálu dne 15. srpna 2020. (neurčitý)
- ↑ Povolení volání virtuálních funkcí v konstantních výrazech . www.open-std.org . Získáno 11. března 2019. Archivováno z originálu 11. června 2018. (neurčitý)
- ↑ P1330R0 - Změna aktivního člena unie uvnitř constexpr . Získáno 13. srpna 2020. Archivováno z originálu dne 26. července 2019. (neurčitý)
- ↑ P1002R0 - Try-catch bloky ve funkcích constexpr . Získáno 8. února 2019. Archivováno z originálu 11. listopadu 2018. (neurčitý)
- ↑ P1327R0 – Povolení dynamického_castu, polymorfního typeid v konstantních výrazech . Získáno 13. srpna 2020. Archivováno z originálu dne 26. července 2019. (neurčitý)
- ↑ Více kontejnerů constexpr . www.open-std.org . Staženo 21. prosince 2020. Archivováno z originálu dne 14. listopadu 2020.
- ↑ Podmíněně explicitní konstruktory C++20 | Blog týmu C++ . Získáno 2. února 2021. Archivováno z originálu dne 23. ledna 2021. (neurčitý)
- ↑ Výchozí porovnání (od C++20) - cppreference.com . Získáno 7. ledna 2022. Archivováno z originálu dne 7. ledna 2022. (neurčitý)
- ↑ Řetězcové literály jako netypové parametry šablony . Archivováno z originálu 11. prosince 2017. (neurčitý)
- ↑ Tim Shen, Richard Smith. P0329R4: Určené znění inicializace . http://www.open-std.org/ . Staženo 21. prosince 2020. Archivováno z originálu dne 15. listopadu 2020.
- ↑ Thomas Köppe. Povolit zachycení lambda [=, toto ] . Staženo 8. února 2019. Archivováno z originálu 9. února 2019. (neurčitý)
- ↑ Známá syntaxe šablony pro generické lambdy . Získáno 8. února 2019. Archivováno z originálu dne 21. listopadu 2018.
- ↑ 1 2 3 Zpráva z cesty: C++ Standards Meeting v Albuquerque, listopad 2017 , je tu Waldo! (20. listopadu 2017). Archivováno z originálu 11. prosince 2017. Staženo 8. února 2019.
- ↑ Formulace pro lambdy v neohodnocených kontextech . Archivováno z originálu 12. prosince 2017. (neurčitý)
- ↑ Výchozí sestavitelné a přiřaditelné bezstavové lambdy . Archivováno z originálu 12. prosince 2017. (neurčitý)
- ↑ Rozšíření balíčku v lambda init-capture . www.open-std.org . Staženo 11. prosince 2017. Archivováno z originálu 14. února 2020. (neurčitý)
- ↑ Archivovaná kopie . Získáno 14. srpna 2020. Archivováno z originálu dne 12. srpna 2020. (neurčitý)
- ↑ P1236R0: Alternativní znění pro P0907R4 Celá čísla se znaménkem jsou doplňkem dvou . Archivováno z originálu 11. listopadu 2018. (neurčitý)
- ↑ P0668R4: Revize modelu paměti C++ . Archivováno z originálu 11. listopadu 2018. (neurčitý)
- ↑ std::make_unique, std::make_unique_for_overwrite - cppreference.com . Získáno 29. ledna 2021. Archivováno z originálu dne 3. února 2021. (neurčitý)
- ↑ std::make_shared, std::make_shared_for_overwrite - cppreference.com . Získáno 29. ledna 2021. Archivováno z originálu dne 3. února 2021. (neurčitý)
- ↑ std::atomic_ref - cppreference.com . Získáno 2. března 2021. Archivováno z originálu dne 27. dubna 2021. (neurčitý)
- ↑ Přijměte konzistentní vymazávání kontejnerů z Library Fundamentals 2 pro C++20 . Získáno 2. února 2021. Archivováno z originálu dne 8. března 2021. (neurčitý)
- ↑ std::map<Key,T,Compare,Alocator>::contains - cppreference.com . Získáno 2. února 2021. Archivováno z originálu 11. června 2018. (neurčitý)
- ↑ Archivovaná kopie . Získáno 2. února 2021. Archivováno z originálu dne 20. ledna 2021. (neurčitý)
- ↑ Nástroj pro převod ukazatele na surový ukazatel . Získáno 2. února 2021. Archivováno z originálu dne 20. února 2018. (neurčitý)
- ↑ Integrace maker pro testování funkcí do C++ WD . Získáno 8. února 2019. Archivováno z originálu dne 20. července 2018. (neurčitý)
- ↑ Zjednodušená aplikace dílčích funkcí . Získáno 2. února 2021. Archivováno z originálu dne 28. září 2020. (neurčitý)
- ↑ Standardní záhlaví knihovny <čísla> - cppreference.com . Získáno 2. března 2021. Archivováno z originálu dne 25. ledna 2021. (neurčitý)
- ↑ P1006R1 - Constexpr v std::pointer_traits . Získáno 8. února 2019. Archivováno z originálu 11. listopadu 2018. (neurčitý)
- ↑ string::empty - Reference C++ . Získáno 29. ledna 2021. Archivováno z originálu dne 28. října 2020. (neurčitý)
- ↑ 100 chyb v projektech Open Source C/C . Získáno 29. ledna 2021. Archivováno z originálu dne 26. ledna 2021. (neurčitý)
- ↑ Knihovna čísel - cppreference.com . Získáno 2. února 2021. Archivováno z originálu dne 21. dubna 2021. (neurčitý)
- ↑ C++20: The Unspoken Features – Human Readable Magazine . Získáno 8. prosince 2020. Archivováno z originálu dne 30. listopadu 2020. (neurčitý)
- ↑ Knihovna formátování (C++20) - cppreference.com . Získáno 29. ledna 2021. Archivováno z originálu dne 31. ledna 2021. (neurčitý)
- ↑ Standardní záhlaví knihovny - cppreference.com . Získáno 29. ledna 2021. Archivováno z originálu dne 27. dubna 2021. (neurčitý)
- ↑ Knihovna rozsahů (C++20) - cppreference.com . Získáno 3. února 2021. Archivováno z originálu dne 16. ledna 2021. (neurčitý)
- ↑ Rozšíření <chrono> na kalendáře a časová pásma . Získáno 3. února 2021. Archivováno z originálu 13. května 2018. (neurčitý)
- ↑ P0342R0: Časové bariéry . Získáno 8. února 2019. Archivováno z originálu dne 24. listopadu 2019. (neurčitý)
- ↑ std::unordered_set<Key,Hash,KeyEqual,Allocator>::find - cppreference.com . Získáno 31. května 2022. Archivováno z originálu dne 31. května 2022. (neurčitý)
- ↑ C++20: Heterogenní vyhledávání v (ne)uspořádaných kontejnerech – příběhy C++ . Získáno 17. května 2022. Archivováno z originálu dne 24. května 2022. (neurčitý)
- ↑ slanění / Tip týdne #144: Heterogenní vyhledávání v asociativních kontejnerech . Získáno 17. května 2022. Archivováno z originálu dne 18. května 2022. (neurčitý)
- ↑ C++ Extensions for Parallelism Version 2 . (neurčitý)
- ↑ C++ Extensions for Reflection . (neurčitý)
- ↑ C++ Extensions for Networking . (neurčitý)
C++ |
---|
|
Zvláštnosti |
|
---|
Některé knihovny |
|
---|
Kompilátory |
|
---|
ovlivnil |
|
---|
|