C++20
Den aktuelle version af siden er endnu ikke blevet gennemgået af erfarne bidragydere og kan afvige væsentligt fra den
version , der blev gennemgået den 17. januar 2022; checks kræver
135 redigeringer .
C++20 er navnet på ISO /IEC-standarden for programmeringssproget C++ . Specifikationen blev offentliggjort i december 2020 [1] .
C++ Standards Committee begyndte at planlægge for C++20 i juli 2017 [2] . C++20 er efterfølgeren til C++17 .
Konstanten er steget til .
__cplusplus202002L
Udelukket og fjernet
Operationer med flygtige er forbudte
Modifikatoren er naturligvis maskinafhængig - til at kommunikere med udstyret. Så det er ikke klart, hvad semantikken for denne eller hin operation er, og hvor mange hukommelsesadgange der vil være. Til synkronisering mellem tråde er det bedre at bruge .
volatileatomic
Følgende operationer med -variabler er forbudt [3] :
volatile
- operationer , ;++--
- operationer og andre (operationer er forbudt i C++23 );+=&=, |=, ^=
- opgave kæder;
- funktioner, parametre og returværdier med modifikator volatile;
- alle de STL-funktioner, der er forbundet med volatile, undtagen nogle f.eks remove_volatile.
atomicYderligere funktioner er blevet tilføjet for at kompensere for det, der blev forbudt
.
Fjernet aggregeret initialisering, når der er en brugerdefineret konstruktør
I tidligere standarder var aggregeret initialisering tilladt, hvis konstruktøren var markeret som eller , hvilket vildledte brugere: Objektet initialiseres uden om konstruktøren.
defaultdelete
struktur X {
int a = 0 ; x () = standard ;
};
X x { 5 }; // C++17: OK // C++20: ingen matchende konstruktør til initialisering af 'X'
Fjernede forbud fra C++17
Fjernede sjældne standardbiblioteksfunktioner forbudt i C++17: [4] [5] [6]
- allocator<void> - viste sig at være uanmeldt;
- nogle af funktionerne allocator er duplikeret af skabelonen allocator_traits;
- raw_storage_iterator - kalder ikke konstruktører og er derfor begrænset i anvendelse;
- get_temporary_buffer - har uoplagte faldgruber;
- is_literal_type - ubrugelig til generisk kode;
- shared_ptr::unique() - på grund af upålidelighed i et flertrådet miljø; hvis du virkelig har brug for det, brug ;use_count
- result_of - erstattet af invoke_result;
- uncaught_exception() - erstattet af uncaught_exceptions.
- <ccomplex>, <ciso646>, <cstdalign>, <cstdbool>, <ctgmath> — har ingen betydning i C++. og andre forlod for kompatibilitet med C.<complex.h>
Bemærkningen blev fjernet fra sproget , som blev erstattet i C++11 af . Hvis du har brug for kompatibilitet med C++03, skal du skrive noget som f.eks
throw()noexcept
#if __cplusplus < 201103L
#define noexcept throw() #endif
Venstre:
- codecvt - faktisk fungerede det meget dårligt, opfordrede udvalget til brug af specialbiblioteker.
- iterator - det er nemmere at skrive iteratorer fra bunden end at bygge videre på det.
- streams - det er ikke klart, hvad der er til gengæld.char*
- implicit oprettelse af "tildel"-operationen, hvis der er en kopikonstruktør og en destruktor (og også en kopikonstruktør, hvis der er en tildeling og en destruktor) - biblioteket er stadig afhængig af denne adfærd.
Andre forbud fra sproget
- Implicit aflytning i lambda-funktioner - på grund af uklar semantik. Eksisterer til optagelse med markør og optagelse med kopi.*this[](){ std::cout << myField; }[this](){ std::cout << myField; }[*this](){ std::cout << myField; }
- "Komma"-operationen i indekser for enhver a, b og c skyldes ikke-oplagt adfærd og ønsket om at skabe en ny syntaks for multidimensionelle arrays [7] . Hvis du virkelig har brug for det, så skriv endelig .a[b,c]a[(b,c)]
- Implicitte konverteringer til en opregnet type - for mere forudsigelig opførsel af den nye rumskibsoperation ( , sammenligning med tre værdier).<=>
- Sammenligning af to arrays - for mere forudsigelig opførsel af den nye operation "stjerneskib" ( , trecifret sammenligning). Mindst én skal konverteres til en pointer.<=>
Andre forbud fra biblioteket
- is_pod - i stedet for det komplekse koncept med " simpel datastruktur ", er det bedre at bruge specifikke typeegenskaber: det er trivielt bygget, trivielt ødelagt osv. Hvis det er meget nødvendigt (for eksempel at overføre data mellem plugins ), er det svarende til .is_trivial && is_standard_layout
- std::rel_ops Den nye Starship-operation gør det bedre.
- atomare kapaciteter - det er ikke klart, hvordan man arbejder med en pointer, atomisk eller ej. Det er bedre at definere det med et typesystem, .shared_ptratomic<shared_ptr>
- string::capacity() - nu besluttet, at det ikke vil reducere kapaciteten.reserve
- filesystem::u8path — er nu anderledes end .u8stringstring
- ATOMIC_FLAG_INIT, atomic_init, ATOMIC_VAR_INIT — nu gør skabelonkonstruktøren det .atomic
Sprog
Mindre ændringer
- Tilføjet usigneret char8_t-type, der kan indeholde UTF-8- enheder .
- using EnumClass, som giver dig mulighed for at gøre koden på vigtige steder mindre rodet.
- Yderligere initialisering i for efter objekt: [8] . Hvis det returnerede objekt er midlertidigt , forlænges dets levetid for hele cyklussen, men andre midlertidige objekter fjernes sikkert, og hvis f() er sandt, er notationen fejlagtig.for (T thing = f(); auto& x : thing.items())items()for (auto& x : f().items())
Moduler
Compiler-direktivet #includevar på et tidspunkt en bekvem C-mekanisme, som faktisk var en cross-platform assembler, der "snyltede" på assembler-værktøjer - linkeren og bibliotekaren. Derfor en vigtig egenskab ved C-kompilere - de var de første, der dukkede op på nye platforme efter assembler. Men med udvidelsen af projekter steg deres kompileringstid kvadratisk: både antallet af oversættelsesenheder og antallet af overskrifter forbundet til dem steg. Modulmekanismen har været et mangeårigt emne for kontroverser siden C++11's dage.
Den indtastede C++20 som følger [9] :
//
helloworld.cpp eksportmodul helloworld ; // modulerklæring import < iostream > ; // importerklæring eksport void hello () { // eksporterklæring std :: cout << "Hej verden! \n " ;
}
Coroutines
En coroutine er en speciel stabelløs funktion, der kan sætte dens udførelse på pause, mens en anden funktion udføres [10] . Coroutinens tilstand gemmes i heap-hukommelsen (medmindre optimeringsværktøjet formåede at slippe af med allokeringen). Ligner en almindelig funktion, men indeholder specielle coroutine-nøgleord .
co_*
opgave <> tcp_echo_server () {
char data [ 1024 ];
for (;;) {
size_t n = co_await socket . async_read_some ( buffer ( data ));
co_await async_write ( socket , buffer ( data , n ));
}
}
Fysisk er en coroutine en funktion, der returnerer et nyskabt løfteobjekt. Hver gang brugeren gør noget med løfteobjektet, overføres kontrollen til coroutine-koden. Flere standardløfter er tilgængelige på biblioteket - giver for eksempel doven evaluering .
lazy<T>
typenavn er erklæret overflødigt, hvor kun type er tilladt
Nogle steder i skabelonerne er ordet typename(der forklarer, at det er en type og ikke en funktion) ikke længere påkrævet [11] . Disse steder omfatter…
Object::Thing
- skriv efter -newauto x = new Object::Thing;
- skriv ind -usingusing Thing = Object::Thing;
- endelig returtype ;auto f() -> Object::Thing
- standardtype i skabelonentemplate<class T = Object::Thing> T f();
- indtast static_cast , const_cast , reinterpret_cast , dynamic_cast --auto x = static_cast<Object::Thing>(y);
- variabel/funktionstype i navneområde (inklusive globalt) eller klasse —Object::Thing variable;
- funktions-/skabelonparametertype, hvis der er en identifikator (undtagen udtryk relateret til beregningen af standardparameterværdien) —void func(Object::Thing x);
skabelon < klasse T > T :: Rf ( ); // OK nu, indtast global navnerumsskabelon < klasse T > void f ( T :: R ) ; // Behøver typenavn, uden det er det et forsøg på at oprette en void variabel initialiseret med T::R skabelon < class T > struct S {
bruger Ptr = PtrTraits < T >:: Ptr ; // Nu OK, skriv ind ved hjælp af T :: R f ( T :: P p ) { // Nu OK, skriv i klassen return static_cast < T :: R > ( p ); // Nu OK, static_cast }
auto g () -> S < T *>:: Ptr ; // OK nu, endelig returtype };
skabelon < typenavn T > void f () {
void ( * pf )( T :: X ); // Forbliver OK, variabel af typen void* initialiseret med T::X void g ( T :: X ); // Behøver typenavn, uden det er det et forsøg på at oprette en void variabel initialiseret med T::X }
Beregning af størrelsen af et array i ny
Matrixstørrelsen i den nye operator trækkes nu automatisk [12]
dobbelt a []{ 1 , 2 , 3 }; // Forbliver OK dobbelt * p = ny dobbelt []{ 1 , 2 , 3 }; // Nu OK
Nye attributter
- [[no_unique_address]] - en variabel uden data optager muligvis ikke plads, og andre variabler kan gemmes i "hullerne" i en variabel med data. Men: variabler af samme type kan aldrig være på samme adresse.
skabelon < class Allocator > klasse Storage {
privat :
[[ no_unique_address ]] Allocator alloc ;
};
- [[nodiscard("причина")]] er en udvidelse af C++17-attributten af samme navn. Angiver, at en funktions returværdi ikke skal ignoreres, og angiver årsagen.
klasse XmlReader { // XML-strømtypelæser offentlig :
[[ nodiscard ( "Tjek resultat eller brug requireTag" )]] bool getTag ( const char * name );
void requireTag ( const char * name ) {
hvis ( ! getTag ( navn ))
throw std :: logic_error ( std :: string ( "requireTag: " ) + navn + " ikke fundet" );
}
};
- [[likely]] / [[unlikely]] - bemærk under hvilke grene det er nødvendigt at optimere programmet for det bedste arbejde af brancheforudsigeren . Denne teknik er faktisk allerede implementeret i nogle compilere, se __builtin_expectf.eks. GCC.
if ( x > y ) [[ usandsynligt ]] {
std :: cout << "Det sker sjældent" << std :: endl ;
} andet [[ sandsynligt ]] {
std :: cout << "Hender ofte" << std :: endl ;
}
Udvidet constexpr
Constexpr tillader:
- kalde virtuelle funktioner [13] ;
- kalde destruktorer, som også skal være ;constexpr
- arbejde med union[14] ;
- arbejde med - skæringsblokken gør intet, og at kaste en undtagelse i denne sammenhæng, som før, vil beregne funktionen under udførelsen [15] ;try
- brug og [16] ;dynamic_casttypeid
- new, med nogle begrænsninger [17] ;
- asmhvis det ikke kaldes ved kompilering;
- uinitialiserede variable.
I teorien vil en sådan konstruktion for eksempel tillade at få en konstant std::vektor til blot at pege på hukommelsen af den tilsvarende std::initializer_list , og en almindelig ikke-konstant alloker dynamisk hukommelse.
Udvidede lambdafunktionskald til kompileringstid - for eksempel kan du sortere std::tuple .
Nøgleord consteval og constinit
constexpr-koden skal ikke kaldes ved kompilering, og det er nok at skrive , så constexpr-kæden brydes ved std::set -konstruktøren og initialisering sker ved udførelse. Nogle gange er dette uønsket - hvis variablen bruges under programinitialisering (en velkendt ulempe ved C++ - en ukontrolleret initialiseringsrækkefølge af CPP-filer), stor (for eksempel en stor tabel) eller svær at beregne (initialisering af samme tabel, som tager O (n²)). Og programmører har bare en sportslig interesse i at overføre koden til kompilering. For at give selvtillid er der brugt to nye søgeord:
std::set<std::string_view> dic { "alpha", "bravo" };
- constevali funktioner: kræver, at funktionen udføres, når den kompileres. Et opkald fra en kontekst, der ikke er eksekverbar ved kompilering, er ikke tilladt. Erstattet i kompatibilitetsoverskrifter med ældre compilere med .constexpr
- constiniti en variabel: kræver, at variablen evalueres på kompileringstidspunktet. Erstattet med en tom streng i kompatibilitetsoverskrifter med ældre compilere.
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 ; // fejl, kan ikke beregnes ved kompilering }
eksplicit (bool)
Nøgleordet kan skrives sammen med et boolesk konstant udtryk: hvis det er sandt, er konverteringen kun mulig eksplicit. Forenkler metaprogrammering, erstatter SFINAE [18] formsprog .
explicit
// Was, std::forward udeladt for
korthedsskabelon < klasse T > struct Wrapper {
skabelon < klasse U , std :: enable_if_t < std :: is_convertible_v < U , T >>* = nullptr >
Indpakning ( U const & u ) : t_ ( u ) {}
skabelon < klasse U , std :: enable_if_t <! std :: is_convertible_v < U , T >>* = nullptr >
eksplicit indpakning ( U const & u ) : t_ ( u ) {}
T t_ ;
};
// Blev
skabelon < class T > struct Wrapper { template < class U > eksplicit ( ! std :: is_convertible_v < U , T > ) Wrapper ( U const & u ) : t_ ( u ) {}
T t_ ; };
Trecifret sammenligning ("stjerneskib")
Operationen giver dig mulighed for at sammenligne objekter ved hjælp af en af tre metoder:
<=>
- Delvis orden : mindre end, ækvivalent, større end, uforlignelig.
- Svag rækkefølge : mindre end, ækvivalent, større end. Det kan ske, at værdien af et offentligt felt eller funktion kan variere for tilsvarende objekter. Begrebet "ækvivalent" er transitivt.
- Stærk (lineær) orden (mindre end, lig, større end). Lige genstande kan kun skelnes efter adresse.
klasse PersonInFamilyTree { // ... public :
std :: partial_ordering operator <=> ( const PersonInFamilyTree & that ) const {
if ( dette -> er_den_samme_person_som ( den )) returner partial_ordering :: tilsvarende ;
if ( dette -> er_transitivt_barn_af ( det )) returner partial_ordering :: mindre ;
if ( det . er_transitivt_barn_af ( * dette )) returner partial_ordering :: større ;
return partial_ordering :: unordered ;
}
};
Navnet "stjerneskib" kommer fra et gammelt Star Trek -spil - disse tre karakterer stod for " Enterprise ".
Kropsversionen af rumskibsoperationen sammenligner simpelthen alle felter i deklarationsrækkefølge. Operationen "er lig med" kroppen er også mulig , den sammenligner også alle felter i deklarationsrækkefølgen og erklærer automatisk operationen "er ikke lig" [19] .
=default=default
Begreber
Koncept - kravene til skabelonens parametre, så denne skabelon giver mening. I det meste af C++'s levetid er konceptet blevet beskrevet verbalt, med komplekse fejl i kendte til gyldige headere som STL, hvis programmøren ikke passede ind i konceptet. Hvis programmøren selv skriver skabelonen, kan han ved et uheld forlade konceptet og ikke se det på testprogrammet, fordi de simpleste typer ser ud til at have mange standardfunktioner som kopikonstruktøren, tildelingen og aritmetiske operationer.
int
skabelon < classT > _
koncept bool EqualityComparable () { return requires ( T a , T b ) {
{ a == b } -> Boolean ; // Et begreb, der betyder en type, der skal konverteres til boolesk { a != b } -> Boolean ;
};
}
Strengkonstanter som skabelonparametre
At kompilere strengbehandling har været en C++-drøm længe, og næste skridt hen imod det er strengkonstanter i skabeloner [20] . Især vil jeg gerne konvertere regulære udtryk til bytekode allerede ved kompilering. Eksperimentelle regex-biblioteker har allerede set speedups på op til 3000 gange sammenlignet med std::regex .
skabelon < auto & str >
void f () {
// str = char const (&)[7]
}
f < "foobar" > ();
Navnet struct-initialisering
Ordinal initialisering af C-strukturer er fejlagtig, hvis udvidelse af strukturen forventes, eller hvis to naboelementer kan forveksles. Den nye standard tilføjet , som eksisterede i C i lang tid, men ikke blev formaliseret i C++ [21] .
Point p { 10, 20 };Point p { .x=10, .y=20 };
Derudover giver denne konstruktion dig mulighed for at initialisere præcis den mulighed union, du har brug for.
union FloatInt {
flyde somFloat ;
int32_t asInt ;
};
FloatInt x { . asInt = 42 };
Fjernet i forhold til C:
- navngivet array-initialisering — startende med C++11, firkantede parenteser i begyndelsen af et udtryk angiver en lambda-funktion.int arr[3] = {[1] = 5};
- erklæring ude af drift - konflikter med C++ autodestruktorer: konstrueret i én rækkefølge, ødelagt i en anden?Point p { .y=20, .x=10 };
- navngivet initialisering af indlejrede strukturmedlemmer - sjældent brugtstruct B b = {.a.x = 0};
- blanding af navngivet og ordinær initialisering:Point p {.x = 1, 2};
Ændringer af lambda-funktioner
Lambda-funktioner dukkede op i C++11 efter andre programmeringssprog. De løser flere problemer på én gang: de erstatter præprocessoren, hvis det er nødvendigt at udføre den samme kode to steder i funktionen, og det er tidskrævende at sætte det ind i et separat objekt/funktion; flyt teksten af funktionen tættere på, hvor den er påkrævet; giver dig mulighed for at skrive i en funktionel stil. Opkaldt efter lambda-regningen , et af grundlaget for funktionel programmering.
Eksplicit aflytning af et objekt i en lambda-funktion [=, this](){}og [=, *this](){}[22] . Som nævnt ovenfor var implicit aflytning i lambda-funktioner forbudt.
this
Traditionel lambda-skabelonsyntaks i stedet for C++14 . Denne syntaks er mere praktisk, hvis du skal lave en selvtest eller beregne en afledt type [23] .
[](auto x)
// Var
auto f = []( auto vektor ) {
bruger T = typenavn decltype ( vektor ) :: værdi_type ;
...
};
// Blev
auto f = [] < typenavn T > ( std :: vektor < T > vektor ) {
...
};
Lambda-funktioner i ikke-beregnelige sammenhænge : signaturer, returtyper, skabelonparametre [24] [25] .
std :: priority_queue <
int , // elementtype std :: vektor < int > , // containertype decltype ( []( int a , int b ) -> bool { // type af elementsammenligningsfunktion returnerer a > b ;
}) > q ;
For at denne kode skal fungere, er der behov for en ændring mere - lambda-funktionen uden kroge har nu en standardkonstruktør og en tildelingsoperator [24] [26] . Alle forekomster af denne pseudo-klasse gør det samme, og der er ingen måde at tvinge en given prioritetskø til at sammenligne i en anden rækkefølge. Kopi- og flytkonstruktører var oprindeligt i alle lambda-funktioner.
I lambdafunktionens aflytningsliste er det nu muligt at beholde operationen med at udvide den variable del [24] [27] - tidligere var det nødvendigt at inkludere et tupelobjekt. For eksempel returnerer denne skabelon en lambda-funktion, der kan kaldes til enhver tid, hvis det ønskes - den kalder foo ()-funktionen og indeholder allerede kopier af alle de data, der er nødvendige for at kalde.
// Var
skabelon < klasse ... Args >
auto delay_invoke_foo ( Args ... args ) {
return [ tup = std :: make_tuple ( std :: move ( args )...)]() -> decltype ( auto ) {
return std :: anvende ([]( auto const & ... args ) -> decltype ( auto ) {
return foo ( args ...);
}, tup );
};
}
// Blev
skabelon < klasse ... Args >
auto delay_invoke_foo ( Args ... args ) {
return [ args = std :: flyt ( args )...]() -> decltype ( auto ) {
return foo ( args ...);
};
}
Redaktionelle ændringer
Nye implicitte flytningsbetingelser
Tydelige betingelser, når det er påkrævet at implicit flytte en genstand, især når du kaster undtagelser: [28]
void f () {
Tx ; _
prøv {
T y ;
prøv { g ( x );}
fange (...) {
hvis ( /*...*/ )
kaste x ; // vil ikke flytte - x udenfor prøveblokken kast y ; // flyt - y inde i prøveblokken }
g ( y );
} fange (...) {
g ( x );
// g(y); // fejl
}
}
Signerede tal - to-komplement
Da C-sproget var i sin vorden, var der en "zoo" af forskellige maskiner, og uddannelsesmaskinen MIX , opfundet af Donald Knuth , afspejlede dette - en byte kunne gemme fra 64 til 100 forskellige værdier og formatet af signerede tal var ikke specificeret. I mere end fyrre år slog de sig på 8-bit byte og to's komplement , primært på grund af enkelhed og interoperabilitet , og dette blev noteret i standarden [29] .
Aritmetisk overløb i aritmetik uden fortegn svarer til modulo-operationer , i aritmetisk- udefineret adfærd med fortegn .
Ny hukommelsesmodel
Mundtligt forældet med C++17 , beregnet til PowerPC og ARM, formaliseret og vendt tilbage til brug. Forstærket [30] .
memory_order_consumememory_order_seq_cst
Bibliotek
Mindre ændringer
- Nye versioner relateret til arrays [31] [32] .make_unique/make_shared
- atomic<shared_ptr<>>og .atomic<weak_ptr<>>
- atomic_ref<>, et objekt, der giver dig mulighed for at gøre noget atomært [33] .
- std::erase, , forenkle metaprogrammering [34] .std::erase_if
- map.contains[35] .
- Den nye header er et standardsted for meddelelser relateret til udviklingen af et bestemt standardbibliotek [36] . Erklæringer er implementeringsdefinerede.<version>
- to_address — konvertering af et pointer-lignende objekt til en pointer [37] . eksisterer allerede, men det kræver dereference, som kan blive udefineret adfærd .addressof
- Nyt #defineat teste compiler og biblioteksfunktionalitet [38] . C++-standarderne er enorme, og ikke alle compiler-udviklere er hurtige til at inkorporere dem i deres produkter. Og nogle - C++11 skraldindsamling - forbliver stubber den dag i dag (2021), ikke implementeret i nogen compiler.
- Forenklet karryning via [39] .bind_front
- source_location - en indpakning til makroer og lignende i C++.__FILE__
- Ny titel med matematiske konstanter [40] . Før det eksisterede selv de sædvanlige π og e kun som forlængelser.<numbers>
Funktionserklæring constexpr
- std::pointer_traits[41] .
- xxx.empty()og nogle andre. Skrivning er i stedet blevet C++ standardfejl [42] [43] , og den erklæres .xxx.empty();xxx.clear();[[nodiscard]]
- <numeric>[44] .
- constructor-destructors af std::vector og std::string , en konsekvens af constexpr-relaksationer. På tidspunktet for gennemgangen (maj 2020) understøtter ingen compiler dette [45] .
Formatering af bibliotek
printf er for lavt, farligt og kan ikke udvides. Standardfunktionerne i C++ tillader kun sammenkædning af strenge og er derfor ubelejlige for lokalisering .
Derfor introducerede C++20 en mere typesikker strengformateringsmekanisme baseret 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 ignoreres på grund af justering <)
Evner:
- Den samme parameter kan formateres et vilkårligt antal gange på forskellige måder.
- Udskiftninger kan byttes.
- Venstre-, center- og højrejustering, et hvilket som helst tegn.
- Som standard er tal, datoer og så videre formateret locale-neutralt; hvis lokalisering er nødvendig, indstilles den eksplicit.
- Arbejder gennem skabeloner og udvides derfor til alle typer.
- Parenteser kan undslippes {{ }} .
Ikke-ejere pointere til et array (span)
std::string_view viste sig at være et fantastisk objekt, og de gjorde det samme for arrays - std::span [47] . Samtidig kan span ændre indholdet af hukommelsen, i modsætning til string_view .
void gør_noget ( std :: span < int > p ) {
std2 :: sort ( p );
for ( int & v : p ) {
v += p [ 0 ];
}
}
// ...
std :: vektor < int > v ;
gøre_noget ( v );
intdata [ 1024 ] ;
gøre_noget ( data );
boost :: container :: small_vector < int , 32 > sm ;
gøre_noget ( sm );
Bibliotek til at arbejde med bits <bit>
Bibliotek til at arbejde med synkroniserede "outputstrømme" <syncstream>
Outputtråden håndterer som regel adgang fra forskellige udførelsestråde på egen hånd . I multi-threaded logging opstår opgaven: at indsamle data (for eksempel en tekstlinje) i en buffer af tilstrækkelig længde og sende dem til strømmen i én operation.
Til dette bruges en simpel klasse, som er en efterkommer af .
ostream
osyncstream { cout } << "Svaret er " << 6 * 7 << endl ;
Alt output til slavetråden sker i en enkelt operation i destruktoren.
Range bibliotek <ranges>
Et komplekst bibliotek bruges, hvor der er behov for ensartet adgang, såsom std::vector og std::deque [48] .
Bibliotek med kalendere og tidszoner i <chrono>
Kompleks bibliotek til kalenderberegninger [49] .
auto d1 = 2018_y / mar / 27 ; _
auto d2 = 27_d / mar / 2018 ; _
auto d3 = mar / 27 / 2018 ;
year_month_day today = floor < dage > ( system_clock :: now ());
hævde ( d1 == d2 );
hævde ( d2 == d3 );
hævde ( d3 == i dag );
Bogstavet j betyder join - det vil sige, når trådobjektet er ødelagt, venter systemet på, at opgaven er færdig.
Derudover kan du ved at bruge biblioteket bede tråden om at stoppe.
stop_token
#inkluder <tråd>
#include <iostream>
bruger navneområde std :: literals :: chrono_literals ;
void f ( std :: stop_token stop_token , int værdi )
{
while ( ! stop_token . stop_requested ()) {
std :: cout << værdi ++ << ' ' << std :: flush ;
std :: denne_tråd :: sleep_for ( 200ms ) ;
}
std :: cout << std :: endl ;
}
int main ()
{
std :: jthread thread ( f , 5 ); // udskriver 5 6 7 8... i cirka 3 sekunder std :: this_thread :: sleep_for ( 3 s );
// Destruktoren af jthread kalder request_stop() og join().
}
Barrierer og bolte
En barriere er en synkroniseringsmekanisme mellem tråde, der fungerer sådan: Så snart n tråde samles ved barrieren , udfører den funktionsobjektet og frigiver dem. Bruges normalt til periodisk koordinering af delvist paralleliserede opgaver: efter at trådene har afsluttet hver deres del, fyrer koordinatoren og beslutter, hvad der skal gøres.
En lås er en forenklet engangsbarriere [50] .
Heterogen søgning i unordered_set / map
Hovedformål: lagringsnøgler er "tunge" objekter (f.eks. streng ), men letvægtsnøgler er også acceptable som søgenøgle: string_view og endda const char*. Det er implementeret meget enkelt: et skabelonfunktionsfund tilføjes, der accepterer enhver type, mens selve den heterogene søgning er inkluderet af markørtypen [51] . Fire funktioner understøttes: find, count, equal_range, contains. C++23 forventer flere funktioner, der understøtter heterogen søgning, såsom slet [52] .
is_transparent
Til selvbalancerende søgetræer ( sæt / kort ) implementeret i C++14.
Denne funktion er ikke aktiveret som standard på grund af en fejl: typekonvertering bevarer muligvis ikke de relationer, som containeren arbejder på. For eksempel , men . Derfor vil søgningen efter et brøktal i ikke føre til det, du har brug for [53] . Så programmøren selv må tillade de alternative nøgler, der helt sikkert er egnede.
1.0 < 1.1static_cast<int>(1.0) == static_cast<int>(1.1)set<int>
struct string_hash {
bruger is_transparent = void ;
[[ nodiscard ]] size_t operator ()( const char * txt ) const {
returner std :: hash < std :: string_view > {}( txt );
}
[[ nodiscard ]] size_t operator ()( std :: string_view txt ) const {
returner std :: hash < std :: string_view > {}( txt );
}
[[ nodiscard ]] size_t operator ()( const std :: string & txt ) const {
returner std :: hash < std :: streng > {}( txt );
}
};
std :: unordered_map < std :: string , int , string_hash , std :: equal_to <>> m { { "Hej Super Lang streng" , 1 }, { "Endnu en lang streng" , 2 }, { "Dette kan ikke falde ind i SSO buffer" , 3 }
};
bool fundet = m . indeholder ( "Hej Super Lang String" );
std :: cout << "Fundet: " << std :: boolalpha << fundet << '\n' ;
Implementeret som eksperimentelle biblioteker
- Concurrency v2 [54] , inklusive opgaveblokke. Version 1 er inkluderet i C++17.
- Refleksion v1 [55]
- Netværk v1 [56]
Tilbage til fremtiden
- Kontrakter - der er et konkurrerende tilbud
- Metaklasser
- Optrædende
- Ejendomme
- Forlænget fremtid
Se også
Noter
- ↑ ISO/IEC 14882:2020 (engelsk) . ISO . Hentet: 21. december 2020.
- ↑ Nuværende status : Standard C++ . Hentet 8. februar 2019. Arkiveret fra originalen 8. september 2020.
- ↑ P1152R4: Udgåvolatile . Hentet 9. august 2022. Arkiveret fra originalen 9. august 2022. (ubestemt)
- ↑ Afskrivning af vestigiale biblioteksdele i C++17 . Hentet 29. januar 2021. Arkiveret fra originalen 13. september 2017. (ubestemt)
- ↑ Udfase <codecvt> . Hentet 29. januar 2021. Arkiveret fra originalen 16. september 2017. (ubestemt)
- ↑ Foreslået resolution for CA 14 (shared_ptr use_count/unique) . Hentet 29. januar 2021. Arkiveret fra originalen 7. juli 2017. (ubestemt)
- ↑ P1161R3: Afvis brug af kommaoperatoren i abonnerende udtryk . www.open-std.org . Hentet 21. december 2020. Arkiveret fra originalen 9. november 2020.
- ↑ Turrapport: Efterår ISO C++ standarder opfylder (Albuquerque) – Sutter's Mill . Hentet 8. februar 2019. Arkiveret fra originalen 13. februar 2019. (ubestemt)
- ↑ Moduler (siden C++20) - cppreference.com . Hentet 2. februar 2021. Arkiveret fra originalen 27. januar 2021. (ubestemt)
- ↑ Coroutines (C++20) - cppreference.com . Hentet 3. februar 2021. Arkiveret fra originalen 25. marts 2021. (ubestemt)
- ↑ Ned med typenavn! . Hentet 13. august 2020. Arkiveret fra originalen 22. april 2018. (ubestemt)
- ↑ Arkiveret kopi . Hentet 14. august 2020. Arkiveret fra originalen 15. august 2020. (ubestemt)
- ↑ Tilladelse af virtuelle funktionsopkald i konstante udtryk . www.open-std.org . Hentet 11. marts 2019. Arkiveret fra originalen 11. juni 2018. (ubestemt)
- ↑ P1330R0 - Ændring af det aktive medlem af en fagforening i constexpr . Hentet 13. august 2020. Arkiveret fra originalen 26. juli 2019. (ubestemt)
- ↑ P1002R0 - Prøv-fangst-blokke i constexpr-funktioner . Hentet 8. februar 2019. Arkiveret fra originalen 11. november 2018. (ubestemt)
- ↑ P1327R0 - Tillader dynamic_cast, polymorf typeid i konstante udtryk . Hentet 13. august 2020. Arkiveret fra originalen 26. juli 2019. (ubestemt)
- ↑ Flere constexpr containere . www.open-std.org . Hentet 21. december 2020. Arkiveret fra originalen 14. november 2020.
- ↑ C++20's betinget eksplicitte konstruktører | C++ teamblog . Hentet 2. februar 2021. Arkiveret fra originalen 23. januar 2021. (ubestemt)
- ↑ Standardsammenligninger (siden C++20) - cppreference.com . Hentet 7. januar 2022. Arkiveret fra originalen 7. januar 2022. (ubestemt)
- ↑ Streng bogstaver som ikke-type skabelonparametre . Arkiveret fra originalen den 11. december 2017. (ubestemt)
- ↑ Tim Shen, Richard Smith. P0329R4: Udpeget initialiseringstekst . http://www.open-std.org/ . Hentet 21. december 2020. Arkiveret fra originalen 15. november 2020.
- ↑ Thomas Köppe. Tillad lambdafangst [=, dette ] . Hentet 8. februar 2019. Arkiveret fra originalen 9. februar 2019. (ubestemt)
- ↑ Velkendt skabelonsyntaks for generiske lambdaer . Hentet 8. februar 2019. Arkiveret fra originalen 21. november 2018.
- ↑ 1 2 3 Turrapport: C++ Standards Meeting i Albuquerque, november 2017 , Der er Waldo! (20. november 2017). Arkiveret fra originalen den 11. december 2017. Hentet 8. februar 2019.
- ↑ Ordlyd for lambdaer i uevaluerede sammenhænge . Arkiveret fra originalen den 12. december 2017. (ubestemt)
- ↑ Standard konstruerbare og tildeles statsløse lambdaer . Arkiveret fra originalen den 12. december 2017. (ubestemt)
- ↑ Pak ekspansion i lambda init-capture . www.open-std.org . Hentet 11. december 2017. Arkiveret fra originalen 14. februar 2020. (ubestemt)
- ↑ Arkiveret kopi . Hentet 14. august 2020. Arkiveret fra originalen 12. august 2020. (ubestemt)
- ↑ P1236R0: Alternativ ordlyd for P0907R4 signerede heltal er tos komplement . Arkiveret fra originalen den 11. november 2018. (ubestemt)
- ↑ P0668R4: Revision af C++-hukommelsesmodellen . Arkiveret fra originalen den 11. november 2018. (ubestemt)
- ↑ std::make_unique, std::make_unique_for_overwrite - cppreference.com . Hentet 29. januar 2021. Arkiveret fra originalen 3. februar 2021. (ubestemt)
- ↑ std::make_shared, std::make_shared_for_overwrite - cppreference.com . Hentet 29. januar 2021. Arkiveret fra originalen 3. februar 2021. (ubestemt)
- ↑ std::atomic_ref - cppreference.com . Hentet 2. marts 2021. Arkiveret fra originalen 27. april 2021. (ubestemt)
- ↑ Adopter Consistent Container Erasure from Library Fundamentals 2 for C++20 . Hentet 2. februar 2021. Arkiveret fra originalen 8. marts 2021. (ubestemt)
- ↑ std::map<Key,T,Compare,Allokator>::contains - cppreference.com . Hentet 2. februar 2021. Arkiveret fra originalen 11. juni 2018. (ubestemt)
- ↑ Arkiveret kopi . Hentet 2. februar 2021. Arkiveret fra originalen 20. januar 2021. (ubestemt)
- ↑ Værktøj til at konvertere en pointer til en rå pointer . Hentet 2. februar 2021. Arkiveret fra originalen 20. februar 2018. (ubestemt)
- ↑ Integrering af funktionstestmakroer i C++ WD . Hentet 8. februar 2019. Arkiveret fra originalen 20. juli 2018. (ubestemt)
- ↑ Forenklet delfunktionsapplikation . Hentet 2. februar 2021. Arkiveret fra originalen 28. september 2020. (ubestemt)
- ↑ Standard biblioteksoverskrift <numbers> - cppreference.com . Hentet 2. marts 2021. Arkiveret fra originalen 25. januar 2021. (ubestemt)
- ↑ P1006R1 - Constexpr i std::pointer_traits . Hentet 8. februar 2019. Arkiveret fra originalen 11. november 2018. (ubestemt)
- ↑ string::empty - C++ Reference . Hentet 29. januar 2021. Arkiveret fra originalen 28. oktober 2020. (ubestemt)
- ↑ 100 fejl i Open Source C/C-projekter . Hentet 29. januar 2021. Arkiveret fra originalen 26. januar 2021. (ubestemt)
- ↑ Numerics library - cppreference.com . Hentet 2. februar 2021. Arkiveret fra originalen 21. april 2021. (ubestemt)
- ↑ C++20: The Unspoken Features - Human Readable Magazine . Hentet 8. december 2020. Arkiveret fra originalen 30. november 2020. (ubestemt)
- ↑ Formateringsbibliotek (C++20) - cppreference.com . Hentet 29. januar 2021. Arkiveret fra originalen 31. januar 2021. (ubestemt)
- ↑ Standardbibliotekets header - cppreference.com . Hentet 29. januar 2021. Arkiveret fra originalen 27. april 2021. (ubestemt)
- ↑ Ranges library (C++20) - cppreference.com . Hentet 3. februar 2021. Arkiveret fra originalen 16. januar 2021. (ubestemt)
- ↑ Udvidelse af <chrono> til kalendere og tidszoner . Hentet 3. februar 2021. Arkiveret fra originalen 13. maj 2018. (ubestemt)
- ↑ P0342R0: Tidsbarrierer . Hentet 8. februar 2019. Arkiveret fra originalen 24. november 2019. (ubestemt)
- ↑ std::unordered_set<Key,Hash,KeyEqual,Allocator>::find - cppreference.com . Hentet 31. maj 2022. Arkiveret fra originalen 31. maj 2022. (ubestemt)
- ↑ C++20: Heterogent opslag i (u)ordnede beholdere - C++-historier . Hentet 17. maj 2022. Arkiveret fra originalen 24. maj 2022. (ubestemt)
- ↑ abseil / Ugens tip #144: Heterogent opslag i associative beholdere . Hentet 17. maj 2022. Arkiveret fra originalen 18. maj 2022. (ubestemt)
- ↑ C++ Extensions for Parallelism Version 2 . (ubestemt)
- ↑ C++ Extensions for Reflection . (ubestemt)
- ↑ C++-udvidelser til netværk . (ubestemt)
C++ |
---|
|
Ejendommeligheder |
|
---|
Nogle biblioteker |
|
---|
Kompilere |
|
---|
påvirket |
|
---|
|