C++20
Den aktuella versionen av sidan har ännu inte granskats av erfarna bidragsgivare och kan skilja sig väsentligt från
versionen som granskades den 17 januari 2022; kontroller kräver
135 redigeringar .
C++20 är namnet på ISO /IEC-standarden för programmeringsspråket C++ . Specifikationen publicerades i december 2020 [1] .
C++ Standards Committee började planera för C++20 i juli 2017 [2] . C++20 är efterföljaren till C++17 .
Konstanten har ökat till .
__cplusplus202002L
Banad och borttagen
Operationer med volatile är förbjudna
Modifieraren är uppenbarligen maskinberoende - för att kommunicera med utrustningen. Så det är inte klart vilken semantik den eller den operationen är och hur många minnesåtkomster det kommer att finnas. För synkronisering mellan trådar är det bättre att använda .
volatileatomic
Följande operationer med -variabler är förbjudna [3] :
volatile
- operationer , ;++--
- operationer och andra (operationer är förbjudna i C++23 );+=&=, |=, ^=
- uppdragskedjor;
- funktioner, parametrar och returvärden med modifierare volatile;
- alla STL-funktioner som är associerade med volatile, förutom vissa liknande remove_volatile;
atomicYtterligare funktioner har lagts till för att kompensera för det som förbjudits
.
Tog bort aggregerad initiering när det finns en anpassad konstruktor
I tidigare standarder tillåts aggregerad initiering om konstruktorn var markerad som eller , vilket vilseledde användare: objektet initieras förbi konstruktorn.
defaultdelete
struktur X {
int a = 0 ; x () = standard ;
};
X x { 5 }; // C++17: OK // C++20: ingen matchande konstruktor för initiering av 'X'
Tog bort förbud från C++17
Tog bort sällsynta standardbiblioteksfunktioner förbjudna i C++17: [4] [5] [6]
- allocator<void> - visade sig vara outtagna;
- några av funktionerna allocator dupliceras av mallen allocator_traits;
- raw_storage_iterator - anropar inte konstruktörer och är därför begränsad i tillämpningen;
- get_temporary_buffer - har otydliga fallgropar;
- is_literal_type - värdelös för generisk kod;
- shared_ptr::unique() - på grund av opålitlighet i en flertrådig miljö; om du verkligen behöver det, använd ;use_count
- result_of - ersatt av invoke_result;
- uncaught_exception() - ersatt av uncaught_exceptions.
- <ccomplex>, <ciso646>, <cstdalign>, <cstdbool>, <ctgmath> — har ingen betydelse i C++. och andra lämnade för kompatibilitet med C.<complex.h>
Anmärkningen togs bort från språket , som ersattes i C++11 med . Om du behöver kompatibilitet med C++03 måste du skriva något liknande
throw()noexcept
#if __cplusplus < 201103L
#define noexcept throw() #endif
Vänster:
- codecvt – i själva verket fungerade det mycket dåligt, kommittén efterlyste användningen av specialiserade bibliotek.
- iterator – det är lättare att skriva iteratorer från grunden än att bygga vidare på det.
- strömmar - det är inte klart vad som är i gengäld.char*
- implicit skapande av "tilldela"-operationen om det finns en kopieringskonstruktör och en destruktor (och även en kopieringskonstruktor om det finns en tilldelning och en destruktor) - biblioteket förlitar sig fortfarande på detta beteende.
Andra förbud från språket
- Implicit avlyssning i lambdafunktioner – på grund av oklar semantik. Finns för att fånga med pekare och fånga med kopia.*this[](){ std::cout << myField; }[this](){ std::cout << myField; }[*this](){ std::cout << myField; }
- "Komma"-operationen i index för alla a, b och c beror på icke-uppenbart beteende och önskan att skapa en ny syntax för flerdimensionella arrayer [7] . Om du verkligen behöver det, skriv gärna .a[b,c]a[(b,c)]
- Implicita omvandlingar till en uppräknad typ - för mer förutsägbart beteende för den nya rymdskeppsoperationen ( , jämförelse med tre värden).<=>
- Jämförelse av två arrayer - för mer förutsägbart beteende för den nya operationen "starship" ( , tresiffrig jämförelse). Minst en måste konverteras till en pekare.<=>
Andra förbud från biblioteket
- is_pod - istället för det komplexa konceptet " enkel datastruktur " är det bättre att använda specifika typegenskaper: det är trivialt byggt, trivialt förstört, etc. Om det är mycket nödvändigt (till exempel att överföra data mellan plugins ) är det motsvarande .is_trivial && is_standard_layout
- std::rel_ops Den nya Starship-operationen gör det bättre.
- atomära förmågor - det är inte klart hur man arbetar med en pekare, atomärt eller inte. Det är bättre att definiera det med ett typsystem, .shared_ptratomic<shared_ptr>
- string::capacity() - nu beslutat att det inte kommer att minska kapaciteten.reserve
- filesystem::u8path — skiljer sig nu från .u8stringstring
- ATOMIC_FLAG_INIT, atomic_init, ATOMIC_VAR_INIT — nu gör mallkonstruktören det .atomic
Språk
Mindre ändringar
- Lade till osignerad char8_t-typ som kan innehålla UTF-8- enheter .
- using EnumClass, vilket gör att du kan göra koden på viktiga platser mindre rörig.
- Ytterligare initiering i för av objekt: [8] . Om det returnerade objektet är temporärt förlängs dess livslängd för hela cykeln, men andra temporära objekt tas bort på ett säkert sätt, och om f() är sant är notationen felaktig.for (T thing = f(); auto& x : thing.items())items()for (auto& x : f().items())
Moduler
Kompilatordirektivet #includevid en tidpunkt var en bekväm C-mekanism, som i själva verket var en plattformsoberoende assembler som "parasiterade" på assemblerverktyg - länkaren och bibliotekarien. Därav en viktig egenskap hos C-kompilatorer - de var de första som dök upp på nya plattformar efter assembler. Men med utbyggnaden av projekt ökade deras sammanställningstid kvadratiskt: både antalet översättningsenheter och antalet rubriker kopplade till dem ökade. Modulmekanismen har varit ett långvarigt ämne för kontroverser sedan C++11:s dagar.
Den kom in i C++20 enligt följande [9] :
//
helloworld.cpp exportmodul helloworld ; // moduldeklaration import < iostream > ; // importdeklaration export void hello () { // exportdeklaration std :: cout << "Hej världen! \n " ;
}
Coroutines
En coroutine är en speciell stackless funktion som kan pausa dess exekvering medan en annan funktion exekverar [10] . Coroutinens tillstånd lagras i heap-minne (såvida inte optimeraren lyckades bli av med allokeringen). Ser ut som en vanlig funktion, men innehåller speciella coroutine-sökord .
co_*
uppgift <> tcp_echo_server () {
char data [ 1024 ];
för (;;) {
size_t n = co_await socket . async_read_some ( buffert ( data ));
co_await async_write ( socket , buffert ( data , n ));
}
}
Fysiskt sett är en coroutine en funktion som returnerar ett nyskapat löftesobjekt. Varje gång användaren gör något med löftesobjektet överförs kontrollen till koroutinkoden. Flera standardlöften finns på biblioteket - ger till exempel lat utvärdering .
lazy<T>
typnamn förklaras redundant där endast typ är tillåten
På vissa ställen i mallarna behövs inte längre ordet typename(som förklarar att det är en typ och inte en funktion) [11] . Dessa platser inkluderar…
Object::Thing
- skriv efter -newauto x = new Object::Thing;
- skriv in -usingusing Thing = Object::Thing;
- slutlig returtyp ;auto f() -> Object::Thing
- standardtyp i malltemplate<class T = Object::Thing> T f();
- skriv in static_cast , const_cast , reinterpret_cast , dynamic_cast -auto x = static_cast<Object::Thing>(y);
- variabel/funktionstyp i namnutrymmet (inklusive globalt) eller klass —Object::Thing variable;
- funktion/mall parametertyp, om det finns en identifierare (förutom uttryck relaterade till beräkningen av standardparametervärdet) —void func(Object::Thing x);
mall < klass T > T :: Rf ( ); // OK nu, skriv in global namnområdesmall < class T > void f ( T :: R ) ; // Behöver typnamn, utan det är det ett försök att skapa en void-variabel initierad med T::R - mall < class T > struct S {
använder Ptr = PtrTraits < T >:: Ptr ; // Nu OK, skriv in med T :: R f ( T :: P p ) { // Nu OK, skriv in class return static_cast < T :: R > ( p ); // Nu OK, static_cast }
auto g () -> S < T *>:: Ptr ; // OK nu, slutlig returtyp };
mall < typnamn T > void f () {
void ( * pf )( T :: X ); // Förblir OK, variabel av typen void* initialiserad med T::X void g ( T :: X ); // Behöver typnamn, utan det är det ett försök att skapa en void-variabel initierad med T::X }
Beräkna storleken på en array i ny
Matrisstorleken i den nya operatorn dras nu automatiskt [12]
dubbla en []{ 1 , 2 , 3 }; // Förblir OK dubbel * p = ny dubbel []{ 1 , 2 , 3 }; // Nu OK
Nya attribut
- [[no_unique_address]] - en variabel utan data kanske inte tar plats, och andra variabler kan lagras i "hålen" i en variabel med data. Men: variabler av samma typ kan aldrig vara på samma adress.
mall < class Allocator > class Storage {
privat :
[[ no_unique_address ]] Allocator alloc ;
};
- [[nodiscard("причина")]] är en förlängning av attributet C++17 med samma namn. Indikerar att en funktions returvärde inte ska ignoreras och matar ut orsaken.
class XmlReader { // Läsare av XML-strömtyp offentlig :
[[ nodiscard ( "Kontrollera resultat eller använd requireTag" )]] bool getTag ( const char * name );
void requireTag ( const char * name ) {
if ( ! getTag ( namn ))
throw std :: logic_error ( std :: string ( "requireTag: " ) + namn + " hittades inte" );
}
};
- [[likely]] / [[unlikely]] - notera under vilka grenar det är nödvändigt att optimera programmet för det bästa arbetet med grenprediktorn . Denna teknik är faktiskt redan implementerad i vissa kompilatorer, se __builtin_expecttill exempel GCC.
if ( x > y ) [[ osannolikt ]] {
std :: cout << "Händer sällan" << std :: endl ;
} annat [[ troligt ]] {
std :: cout << "Händer ofta" << std :: endl ;
}
Utökad constexpr
Constexpr tillåter:
- anropa virtuella funktioner [13] ;
- kalla förstörare, som också måste vara ;constexpr
- arbeta med union[14] ;
- arbeta med - intercept-blocket gör ingenting, och om du kastar ett undantag i detta sammanhang, som tidigare, kommer funktionen att beräknas under exekvering [15] ;try
- använd och [16] ;dynamic_casttypeid
- new, med vissa begränsningar [17] ;
- asmom det inte kallas vid sammanställning;
- oinitierade variabler.
I teorin kommer en sådan konstruktion att tillåta till exempel att få en konstant std::vektor att helt enkelt peka på minnet för motsvarande std::initializer_list , och ett vanligt icke-konstant allokeringsdynamiskt minne.
Utökade lambdafunktionsanrop vid kompileringstid - du kan till exempel sortera std::tuple .
Nyckelord consteval och constinit
constexpr-koden behöver inte anropas vid kompilering, och det räcker med att skriva så att constexpr-kedjan bryts vid std::set -konstruktorn och initialisering sker vid exekvering. Ibland är detta oönskat - om variabeln används under programinitiering (en välkänd nackdel med C++ - en okontrollerad initialiseringsordning av CPP-filer), stor (till exempel en stor tabell) eller svår att beräkna (initiering av samma tabell, som tar O (n²)). Och programmerare har bara ett sportintresse av att överföra koden till kompilering. För att ge förtroende används två nya sökord:
std::set<std::string_view> dic { "alpha", "bravo" };
- constevali funktioner: kräver att funktionen körs när den kompileras. Ett anrop från en kontext som inte är körbar vid kompilering är inte tillåten. Ersatt i kompatibilitetshuvuden med äldre kompilatorer med .constexpr
- constiniti en variabel: kräver att variabeln utvärderas vid kompileringstillfället. Ersatt med en tom sträng i kompatibilitetsrubriker med äldre kompilatorer.
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 ; // fel, ej beräknad vid kompilering }
explicit (bool)
Nyckelordet kan skrivas tillsammans med ett booleskt konstantuttryck: om det är sant är konverteringen endast möjlig explicit. Förenklar metaprogrammering, ersätter SFINAE [18] idiom .
explicit
// Was, std::forward utelämnad för
korthetsmall < class T > struct Wrapper {
mall < klass U , std :: enable_if_t < std :: is_convertible_v < U , T >>* = nullptr >
Omslag ( U const & u ) : t_ ( u ) {}
mall < klass U , std :: enable_if_t <! std :: is_convertible_v < U , T >>* = nullptr >
explicit omslag ( U const & u ) : t_ ( u ) {}
T t_ ;
};
// Blev
mall < class T > struct Wrapper { template < class U > explicit ( ! std :: is_convertible_v < U , T > ) Wrapper ( U const & u ) : t_ ( u ) {}
T t_ ; };
Tresiffrig jämförelse ("stjärnskepp")
Operationen låter dig jämföra objekt med en av tre metoder:
<=>
- Delordning : mindre än, ekvivalent, större än, ojämförlig.
- Svag ordning : mindre än, ekvivalent, större än. Det kan hända att värdet på något offentligt fält eller funktion kan skilja sig åt för motsvarande objekt. Begreppet "motsvarande" är transitivt.
- Stark (linjär) ordning (mindre än, lika, större än). Lika objekt kan endast särskiljas genom adress.
class PersonInFamilyTree { // ... public :
std :: partial_ordering operator <=> ( const PersonInFamilyTree & that ) const {
if ( detta -> är_samma_person_som ( den )) returnera partial_ordering :: ekvivalent ;
if ( this -> is_transitive_child_of ( that )) return partial_ordering :: less ;
if ( det . är_transitivt_barn_av ( * detta )) returnerar partiell_ordning :: större ;
return partial_ordering :: unordered ;
}
};
Namnet "starship" kommer från ett gammalt Star Trek -spel - dessa tre karaktärer stod för " Enterprise ".
Kroppsversionen av rymdskeppsoperationen jämför helt enkelt alla fält i deklarationsordning. Operationen "likar" med kroppen är också möjlig , den jämför också alla fält i deklarationsordningen och deklarerar automatiskt operationen "inte lika" [19] .
=default=default
Begrepp
Koncept - kraven på mallens parametrar så att denna mall är vettig. Under större delen av C++s liv har konceptet beskrivits verbalt, med komplexa fel i kända till giltiga rubriker som STL om programmeraren inte passade in i konceptet. Om programmeraren skriver mallen själv kan han av misstag lämna konceptet och inte se det i testprogrammet, eftersom de enklaste typerna verkar ha många standardfunktioner som kopieringskonstruktorn, tilldelningen och aritmetiska operationer.
int
mall < classT > _
koncept bool EqualityComparable () { return requires ( T a , T b ) {
{ a == b } -> Boolean ; // Ett begrepp som betyder en typ som ska konverteras till boolesk { a != b } -> Boolean ;
};
}
Strängkonstanter som mallparametrar
Att kompilera strängbearbetning har varit en C++-dröm länge, och nästa steg mot det är strängkonstanter i mallar [20] . I synnerhet skulle jag vilja konvertera reguljära uttryck till bytekod redan vid kompilering. Experimentella regex-bibliotek har redan sett hastigheter på upp till 3000 gånger jämfört med std::regex .
mall < auto & str >
void f () {
// str = char const (&)[7]
}
f < "foobar" > ();
Namngiven struct-initiering
Ordinal initiering av C-strukturer är felaktig om expansion av strukturen förväntas, eller om två angränsande element kan förväxlas. Den nya standarden lades till , som funnits i C under lång tid, men inte formaliserad i C++ [21] .
Point p { 10, 20 };Point p { .x=10, .y=20 };
Dessutom låter denna konstruktion dig initiera exakt det alternativ uniondu behöver.
union FloatInt {
flyta somFlöta ;
int32_t asInt ;
};
FloatInt x { . asInt = 42 };
Borttagen jämfört med C:
- namngiven arrayinitiering — börjar med C++11, hakparenteser i början av ett uttryck anger en lambdafunktion.int arr[3] = {[1] = 5};
- deklaration ur funktion - konflikter med C++ autodestruktorer: konstruerad i en ordning, förstörd i en annan?Point p { .y=20, .x=10 };
- namngiven initiering av kapslade strukturmedlemmar - används sällanstruct B b = {.a.x = 0};
- blandning av namngiven och ordinär initialisering:Point p {.x = 1, 2};
Ändringar av lambdafunktioner
Lambdafunktioner dök upp i C++11 efter andra programmeringsspråk. De löser flera problem på en gång: de ersätter förprocessorn om det är nödvändigt att köra samma kod på två ställen i funktionen, och det är tidskrävande att lägga in den i ett separat objekt/funktion; flytta funktionens text närmare där den krävs; låter dig skriva i en funktionell stil. Uppkallad efter lambdakalkylen , en av grunderna för funktionell programmering.
Explicit avlyssning av ett objekt i en lambdafunktion [=, this](){}och [=, *this](){}[22] . Som nämnts ovan förbjöds implicit avlyssning i lambdafunktioner.
this
Traditionell lambda-mallsyntax istället för C++14 . Denna syntax är bekvämare om du behöver göra ett självtest, eller beräkna någon härledd typ [23] .
[](auto x)
// Var
auto f = []( auto vektor ) {
använder T = typnamn decltype ( vektor ) :: värde_typ ;
...
};
// Blev
auto f = [] < typnamn T > ( std :: vektor < T > vektor ) {
...
};
Lambda fungerar i icke beräkningsbara sammanhang : signaturer, returtyper, mallparametrar [24] [25] .
std :: priority_queue <
int , // elementtyp std :: vektor < int > , // containertyp decltype ( []( int a , int b ) -> bool { // typ av elementjämförelsefunktion return a > b ;
}) > q ;
För att den här koden ska fungera krävs ytterligare en ändring - lambdafunktionen utan krokar har nu en standardkonstruktor och en tilldelningsoperator [24] [26] . Alla instanser av denna pseudoklass gör samma sak, och det finns inget sätt att tvinga en given prioritetskö att jämföra i en annan ordning. Kopiera och flytta konstruktörer fanns ursprungligen i alla lambda-funktioner.
I avlyssningslistan för lambdafunktionen är det nu möjligt att behålla operationen att expandera den variabla delen [24] [27] - tidigare var det nödvändigt att inkludera ett tupelobjekt för detta. Till exempel returnerar den här mallen en lambda-funktion som kan anropas när som helst om så önskas - den anropar foo ()-funktionen och innehåller redan kopior av all data som behövs för att anropa.
// Var
mall < klass ... Args >
auto delay_invoke_foo ( Args ... args ) {
return [ tup = std :: make_tuple ( std :: move ( args )...)]() -> decltype ( auto ) {
return std :: tillämpa ([]( auto const & ... args ) -> decltype ( auto ) {
return foo ( args ...);
}, tup );
};
}
// Blev
mall < klass ... Args >
auto delay_invoke_foo ( Args ... args ) {
return [ args = std :: flytta ( args )...]() -> decltype ( auto ) {
return foo ( args ...);
};
}
Redaktionella ändringar
Nya implicita rörelsevillkor
Förtydligade villkor när det krävs att implicit flytta ett objekt, särskilt när du kastar undantag: [28]
void f () {
Tx ; _
prova {
T y ;
försök { g ( x );}
fånga (...) {
om ( /*...*/ )
kasta x ; // kommer inte att flytta - x utanför försöksblocket kasta y ; // flytta - y inuti försöksblocket }
g ( y );
} fånga (...) {
g ( x );
// g(y); // fel
}
}
Signerade nummer - tvås komplement
När C-språket var i sin linda fanns det ett "zoo" av olika maskiner, och utbildningsmaskinen MIX , uppfunnen av Donald Knuth , återspeglade detta - en byte kunde lagra från 64 till 100 olika värden, och formatet av signerade nummer specificerades inte. I mer än fyrtio år bestämde de sig för 8-bitars byte och två- komplement , främst på grund av enkelhet och interoperabilitet , och detta noterades i standarden [29] .
Aritmetiskt spill i aritmetik utan tecken är likvärdigt med modulooperationer , i aritmetiskt odefinierat beteende med tecken .
Ny minnesmodell
Oralt utfasad med C++17 , avsedd för PowerPC och ARM, formaliserad och återställd till användning. Förstärkt [30] .
memory_order_consumememory_order_seq_cst
Bibliotek
Mindre ändringar
- Nya versioner relaterade till arrayer [31] [32] .make_unique/make_shared
- atomic<shared_ptr<>>och .atomic<weak_ptr<>>
- atomic_ref<>, ett föremål som låter dig göra vad som helst atomärt [33] .
- std::erase, , förenkla metaprogrammering [34] .std::erase_if
- map.contains[35] .
- Den nya rubriken är en standardplats för meddelanden relaterade till utvecklingen av ett visst standardbibliotek [36] . Deklarationer är implementeringsdefinierade.<version>
- to_address — omvandling av ett pekliknande objekt till en pekare [37] . existerar redan, men det kräver dereference, vilket kan bli odefinierat beteende .addressof
- Nytt #defineför att testa kompilator- och biblioteksfunktionalitet [38] . C++-standarderna är enorma, och inte alla kompilatorutvecklare är snabba med att införliva dem i sina produkter. Och vissa - C++11 sophämtning - förblir stubbar till denna dag (2021), inte implementerade i någon kompilator.
- Förenklad curryning via [39] .bind_front
- source_location - ett omslag för makron och liknande i C++.__FILE__
- Ny titel med matematiska konstanter [40] . Innan dess existerade även de vanliga π och e bara som förlängningar.<numbers>
Funktionsdeklaration constexpr
- std::pointer_traits[41] .
- xxx.empty()och några andra. Skrivandet har istället blivit C++ standardfel [42] [43] , och det deklareras .xxx.empty();xxx.clear();[[nodiscard]]
- <numeric>[44] .
- constructor-destructors av std::vector och std::string , en konsekvens av constexpr-avslappningar. Vid tidpunkten för granskning (maj 2020) stöder ingen kompilator detta [45] .
Formatera bibliotek
printf är för låg nivå, farligt och går inte att utöka. Standardfunktionerna i C++ tillåter endast sammanlänkning av strängar och är därför obekväma för lokalisering .
Därför introducerade C++20 en mer typsäker strängformateringsmekanism baserad på Python [46] .
char c = 120 ;
auto s1 = std :: format ( "{:+06d}" , c ); // "+00120" auto s2 = std :: format ( "{:#06x}" , 0xa ); // "0x000a" auto s3 = std :: format ( "{:<06}" , -42 ); // "-42 " (0 ignoreras på grund av justering <)
Förmågor:
- Samma parameter kan formateras hur många gånger som helst på olika sätt.
- Byten kan bytas ut.
- Vänster-, mitt- och högerjustering, vilket tecken som helst.
- Som standard är siffror, datum och så vidare formaterade språkneutralt; om lokalisering behövs ställs den in explicit.
- Fungerar genom mallar och sträcker sig därför till alla typer.
- Parenteser kan undvikas {{ }} .
Icke-ägande pekare till en array (span)
std::string_view visade sig vara ett bra objekt, och de gjorde samma sak för arrayer - std::span [47] . Samtidigt kan span ändra innehållet i minnet, till skillnad från string_view .
void do_something ( std :: span < int > p ) {
std2 :: sortera ( p );
för ( int & v : p ) {
v += p [ 0 ];
}
}
// ...
std :: vektor < int > v ;
göra_något ( v );
intdata [ 1024 ] ;
göra_något ( data );
boost :: container :: small_vector < int , 32 > sm ;
göra_något ( sm );
Bibliotek för att arbeta med bitar <bit>
- Räknar antalet bitar
- Avrundning till tvås kraft
- Bit-till-bit-konvertering från en typ till en annan (se snabb invers kvadratrot )
- Rotera , en standardfunktion hos många processorer
- Bestämma målmaskinens endianness
Bibliotek för att arbeta med synkroniserade "utgångsströmmar" <syncstream>
Utdatatråden hanterar som regel åtkomst från olika exekveringstrådar på egen hand . I flertrådsloggning uppstår uppgiften: att samla in data (till exempel en textrad) i en buffert med tillräcklig längd och mata ut dem till strömmen i en operation.
För detta används en enkel klass, som är en ättling till .
ostream
osyncstream { cout } << "Svaret är " << 6 * 7 << endl ;
All utmatning till slavtråden sker i en enda operation i destruktorn.
Range library <ranges>
Ett komplext bibliotek används där enhetlig åtkomst behövs, såsom std::vector och std::deque [48] .
Bibliotek med kalendrar och tidszoner i <chrono>
Komplext bibliotek för kalenderberäkningar [49] .
auto d1 = 2018_y / mar / 27 ; _
auto d2 = 27_d / mar / 2018 ; _
auto d3 = mar / 27 / 2018 ;
year_month_day today = floor < days > ( system_clock :: now ());
hävda ( dl == d2 );
hävda ( d2 == d3 );
hävda ( d3 == idag );
Bokstaven j betyder join - det vill säga när trådobjektet förstörs väntar systemet på att uppgiften ska slutföras.
Med hjälp av biblioteket kan du dessutom be tråden att sluta.
stop_token
#inkludera <tråd>
#include <iostream>
använder namnutrymme std :: literals :: chrono_literals ;
void f ( std :: stop_token stop_token , int värde )
{
while ( ! stop_token . stop_requested ()) {
std :: cout << värde ++ << ' ' << std :: flush ;
std :: denna_tråd :: sleep_for ( 200ms ) ;
}
std :: cout << std :: endl ;
}
int main ()
{
std :: jthread thread ( f , 5 ); // skriver ut 5 6 7 8... i ungefär 3 sekunder std :: this_thread :: sleep_for ( 3 s );
// Destruktören för jthread anropar request_stop() och join().
}
Barriärer och bultar
En barriär är en synkroniseringsmekanism mellan trådar som fungerar så här: så snart n trådar samlas vid barriären , exekverar den funktionsobjektet och släpper dem. Används vanligtvis för periodisk koordinering av delvis parallelliserade uppgifter: efter att trådarna har avslutat var sin del, avfyrar koordinatorn och bestämmer vad som ska göras härnäst.
En spärr är en förenklad engångsbarriär [50] .
Heterogen sökning i unordered_set / map
Huvudsyftet: lagringsnycklar är "tunga" objekt (till exempel sträng ), men lätta sådana är också acceptabla som söknyckel: string_view och även const char*. Det är implementerat väldigt enkelt: ett mallfunktionsfynd läggs till som accepterar vilken typ som helst, medan den heterogena sökningen i sig ingår av markörtypen [51] . Fyra funktioner stöds: find, count, equal_range, contains. C++23 förväntar sig fler funktioner som stöder heterogen sökning, såsom radera [52] .
is_transparent
För självbalanserande sökträd ( set / map ) implementerade i C++14.
Den här funktionen är inte aktiverad som standard på grund av en bugg: typkonvertering kanske inte bevarar relationerna som behållaren fungerar på. Till exempel men . Därför kommer sökningen efter ett bråktal i inte att leda till det du behöver [53] . Så programmeraren själv måste tillåta de alternativa nycklar som verkligen är lämpliga.
1.0 < 1.1static_cast<int>(1.0) == static_cast<int>(1.1)set<int>
struct string_hash {
använder is_transparent = void ;
[[ nodiscard ]] size_t operator ()( const char * txt ) const {
return std :: hash < std :: string_view > {}( txt );
}
[[ nodiscard ]] size_t operator ()( std :: string_view txt ) const {
return std :: hash < std :: string_view > {}( txt );
}
[[ nodiscard ]] size_t operator ()( const std :: string & txt ) const {
return std :: hash < std :: sträng > {}( txt );
}
};
std :: unordered_map < std :: string , int , string_hash , std :: equal_to <>> m { { "Hej superlång sträng" , 1 }, { "Another Longish String" , 2 }, { "Detta kan inte falla in i SSO-buffert" , 3 }
};
bool funnen = m . innehåller ( "Hej superlång sträng" );
std :: cout << "Found: " << std :: boolalpha << hittat << '\n' ;
Implementerat som experimentbibliotek
- Samtidighet v2 [54] , inklusive uppgiftsblock. Version 1 ingår i C++17.
- Reflektion v1 [55]
- Nätverk v1 [56]
Kvar för framtiden
- Kontrakt - det finns ett konkurrerande erbjudande
- Metaklasser
- Skådespelare
- Egenskaper
- Förlängd framtid
Se även
Anteckningar
- ↑ ISO/IEC 14882:2020 (engelska) . ISO . Hämtad: 21 december 2020.
- ↑ Nuvarande status : Standard C++ . Hämtad 8 februari 2019. Arkiverad från originalet 8 september 2020.
- ↑ P1152R4: Utfasasvolatile . Hämtad 9 augusti 2022. Arkiverad från originalet 9 augusti 2022. (obestämd)
- ↑ Utfasning av Vestigial Library Parts i C++17 . Hämtad 29 januari 2021. Arkiverad från originalet 13 september 2017. (obestämd)
- ↑ Utfasar <codecvt> . Hämtad 29 januari 2021. Arkiverad från originalet 16 september 2017. (obestämd)
- ↑ Förslag till resolution för CA 14 (shared_ptr use_count/unique) . Hämtad 29 januari 2021. Arkiverad från originalet 7 juli 2017. (obestämd)
- ↑ P1161R3: Ta bort användningen av kommaoperatorn i prenumerationsuttryck . www.open-std.org . Hämtad 21 december 2020. Arkiverad från originalet 9 november 2020.
- ↑ Reserapport: Fall ISO C++-standarder som möter (Albuquerque) – Sutter's Mill . Hämtad 8 februari 2019. Arkiverad från originalet 13 februari 2019. (obestämd)
- ↑ Moduler (sedan C++20) - cppreference.com . Hämtad 2 februari 2021. Arkiverad från originalet 27 januari 2021. (obestämd)
- ↑ Coroutines (C++20) - cppreference.com . Hämtad 3 februari 2021. Arkiverad från originalet 25 mars 2021. (obestämd)
- ↑ Ner med typnamn! . Hämtad 13 augusti 2020. Arkiverad från originalet 22 april 2018. (obestämd)
- ↑ Arkiverad kopia . Hämtad 14 augusti 2020. Arkiverad från originalet 15 augusti 2020. (obestämd)
- ↑ Tillåter virtuella funktionsanrop i konstanta uttryck . www.open-std.org . Hämtad 11 mars 2019. Arkiverad från originalet 11 juni 2018. (obestämd)
- ↑ P1330R0 - Ändra den aktiva medlemmen i ett fackförbund inom constexpr . Hämtad 13 augusti 2020. Arkiverad från originalet 26 juli 2019. (obestämd)
- ↑ P1002R0 - Try-catch-block i constexpr-funktioner . Hämtad 8 februari 2019. Arkiverad från originalet 11 november 2018. (obestämd)
- ↑ P1327R0 - Tillåter dynamic_cast, polymorphic typeid i konstanta uttryck . Hämtad 13 augusti 2020. Arkiverad från originalet 26 juli 2019. (obestämd)
- ↑ Fler constexpr- behållare . www.open-std.org . Hämtad 21 december 2020. Arkiverad från originalet 14 november 2020.
- ↑ C++20:s villkorligt explicita konstruktörer | C++ Team Blog . Hämtad 2 februari 2021. Arkiverad från originalet 23 januari 2021. (obestämd)
- ↑ Standardjämförelser (sedan C++20) - cppreference.com . Hämtad 7 januari 2022. Arkiverad från originalet 7 januari 2022. (obestämd)
- ↑ Strängliteraler som mallparametrar av icke-typ . Arkiverad från originalet den 11 december 2017. (obestämd)
- ↑ Tim Shen, Richard Smith. P0329R4: Avsedd initialiseringsformulering . http://www.open-std.org/ . Hämtad 21 december 2020. Arkiverad från originalet 15 november 2020.
- ↑ Thomas Köppe. Tillåt lambdafångst [=, detta ] . Hämtad 8 februari 2019. Arkiverad från originalet 9 februari 2019. (obestämd)
- ↑ Bekant mallsyntax för generiska lambdas . Hämtad 8 februari 2019. Arkiverad från originalet 21 november 2018.
- ↑ 1 2 3 Reserapport: C++ Standards Meeting i Albuquerque, november 2017 , där är Waldo! (20 november 2017). Arkiverad från originalet den 11 december 2017. Hämtad 8 februari 2019.
- ↑ Formulering för lambdas i outvärderade sammanhang . Arkiverad från originalet den 12 december 2017. (obestämd)
- ↑ Standard konstruerbara och tilldelbara tillståndslösa lambdas . Arkiverad från originalet den 12 december 2017. (obestämd)
- ↑ Packa expansion i lambda init-capture . www.open-std.org . Hämtad 11 december 2017. Arkiverad från originalet 14 februari 2020. (obestämd)
- ↑ Arkiverad kopia . Hämtad 14 augusti 2020. Arkiverad från originalet 12 augusti 2020. (obestämd)
- ↑ P1236R0: Alternativ formulering för P0907R4 signerade heltal är tvås komplement . Arkiverad från originalet den 11 november 2018. (obestämd)
- ↑ P0668R4: Revidering av C++-minnesmodellen . Arkiverad från originalet den 11 november 2018. (obestämd)
- ↑ std::make_unique, std::make_unique_for_overwrite - cppreference.com . Hämtad 29 januari 2021. Arkiverad från originalet 3 februari 2021. (obestämd)
- ↑ std::make_shared, std::make_shared_for_overwrite - cppreference.com . Hämtad 29 januari 2021. Arkiverad från originalet 3 februari 2021. (obestämd)
- ↑ std::atomic_ref - cppreference.com . Hämtad 2 mars 2021. Arkiverad från originalet 27 april 2021. (obestämd)
- ↑ Adoptera Consistent Container Erasure from Library Fundamentals 2 för C++20 . Hämtad 2 februari 2021. Arkiverad från originalet 8 mars 2021. (obestämd)
- ↑ std::map<Key,T,Compare,Allocator>::contains - cppreference.com . Hämtad 2 februari 2021. Arkiverad från originalet 11 juni 2018. (obestämd)
- ↑ Arkiverad kopia . Hämtad 2 februari 2021. Arkiverad från originalet 20 januari 2021. (obestämd)
- ↑ Verktyg för att konvertera en pekare till en rå pekare . Hämtad 2 februari 2021. Arkiverad från originalet 20 februari 2018. (obestämd)
- ↑ Integrera funktionstestmakron i C++ WD . Hämtad 8 februari 2019. Arkiverad från originalet 20 juli 2018. (obestämd)
- ↑ Förenklad delfunktionsapplikation . Hämtad 2 februari 2021. Arkiverad från originalet 28 september 2020. (obestämd)
- ↑ Standardbibliotekshuvud <nummer> - cppreference.com . Hämtad 2 mars 2021. Arkiverad från originalet 25 januari 2021. (obestämd)
- ↑ P1006R1 - Constexpr i std::pointer_traits . Hämtad 8 februari 2019. Arkiverad från originalet 11 november 2018. (obestämd)
- ↑ string::empty - C++ Referens . Hämtad 29 januari 2021. Arkiverad från originalet 28 oktober 2020. (obestämd)
- ↑ 100 buggar i C/C-projekt med öppen källkod . Hämtad 29 januari 2021. Arkiverad från originalet 26 januari 2021. (obestämd)
- ↑ Numerics library - cppreference.com . Hämtad 2 februari 2021. Arkiverad från originalet 21 april 2021. (obestämd)
- ↑ C++20: The Unspoken Features - Människoläsbar tidskrift . Hämtad 8 december 2020. Arkiverad från originalet 30 november 2020. (obestämd)
- ↑ Formateringsbibliotek (C++20) - cppreference.com . Hämtad 29 januari 2021. Arkiverad från originalet 31 januari 2021. (obestämd)
- ↑ Standardbibliotekshuvud - cppreference.com . Hämtad 29 januari 2021. Arkiverad från originalet 27 april 2021. (obestämd)
- ↑ Ranges library (C++20) - cppreference.com . Hämtad 3 februari 2021. Arkiverad från originalet 16 januari 2021. (obestämd)
- ↑ Utöka <chrono> till kalendrar och tidszoner . Hämtad 3 februari 2021. Arkiverad från originalet 13 maj 2018. (obestämd)
- ↑ P0342R0: Tidsbarriärer . Hämtad 8 februari 2019. Arkiverad från originalet 24 november 2019. (obestämd)
- ↑ std::unordered_set<Key,Hash,KeyEqual,Allocator>::find - cppreference.com . Hämtad 31 maj 2022. Arkiverad från originalet 31 maj 2022. (obestämd)
- ↑ C++20: Heterogen sökning i (o)ordnade behållare - C++-berättelser . Hämtad 17 maj 2022. Arkiverad från originalet 24 maj 2022. (obestämd)
- ↑ nedfiring/veckans tips #144: Heterogen sökning i associativa behållare . Hämtad 17 maj 2022. Arkiverad från originalet 18 maj 2022. (obestämd)
- ↑ C++ Extensions for Parallelism Version 2 . (obestämd)
- ↑ C++ Extensions for Reflection . (obestämd)
- ↑ C++-tillägg för nätverk . (obestämd)
C++ |
---|
|
Egenheter |
|
---|
Vissa bibliotek |
|
---|
Kompilatorer |
|
---|
påverkas |
|
---|
|