C++17

Den aktuella versionen av sidan har ännu inte granskats av erfarna bidragsgivare och kan skilja sig väsentligt från versionen som granskades den 5 maj 2021; kontroller kräver 17 redigeringar .

C++17 (även känd som C++1z) är namnet på ISO /IEC-versionen av C++-standarden. Specifikationerna för C++17 publicerades i december 2017 [1] [2] .

Värdet på konstanten __cplusplushar blivit 201703L, detta används för villkorlig kompilering .

Borttagen eller förbjuden

Borttagna trigrafer

Trigrafer användes för maskiner med icke-standardkodning och/eller begränsade tangentbord. Tillbaka i slutet av 80-talet, med spridningen av 8-bitars kodningar och billiga gummimembrantangentbord , förlorade trigrafer faktiskt sin betydelse, och trettio år senare uteslöts de naturligt [3] [4] .

// Kommer nästa rad att köras????????????????????/ a ++ ; /* med trigrafer kommenteras denna linje bort - trigraf ??/ motsvarar \ */

Borttaget register nyckelord

C-språket var en "portabel assembler": det gjorde det möjligt att göra snabba program som kompileras på olika datorer, och det använde också assemblerverktyg ( linker , bibliotekarie). Begrepp som " huvudfil " och " översättningsenhet " är ekon från den tiden.

Ordet registerförknippades ursprungligen med den manuella optimeringen av programmet. Moderna kompilatorer "under huven" gör ett stort antal optimeringar, och sådan manuell kontroll verkar överflödig. Tillbaka i C++11 förklarades ordet oönskat. Ordet är fortfarande reserverat och kan någon dag användas för ett annat syfte - som i C++11 [5] . auto

Tog bort ++ operation för bool

Operationen är uppenbarligen osäker och är förbjuden i C++98 [6] . Operationen --saknas.

Tog bort deklarerade undantag

Deklarerade undantag void f() throw(A, B, C);, som finns i Java till exempel, gör mer skada än nytta. Banad i C++11, borttagen i C++17. Kvar throw()som en synonym för noexcept(true)[7] .

Tog bort typer och funktioner som ersattes (och förbjöds) i C++11

Bland dem finns std::auto_ptrgamla std::random_shufflefunktionsadaptrar [8] [9] .

Istället används unique_ptr, shuffleoch nya funktionsmallar baserade på function/ bind. Det hävdas att vilken kod som helst på auto_ptrkan konverteras mekaniskt till unique_ptr, med ett enkelt tillägg std::movedär det sker en övergång av äganderätten.

Separata delar iostreamförbjudna i C++98 [10] har också tagits bort .

Tog bort konstruktorer för std::funktion som tog en allokator

Fem överbelastningar totalt, inklusive denna

mall < classAlloc > _ function ( std :: allocator_arg_t , const Alloc & alloc ) noexcept ;

På grund av obegriplig semantik och implementeringssvårigheter togs de bort utan föregående förbud [11] .

Extremt sällsynta funktioner i standardbiblioteket är förbjudna

Flera sällsynta funktioner i standardbiblioteket är förbjudna: [12] [13] [14]

  • 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, men kvar så länge det finns ett koncept av "bokstavlig typ" i C++;
  • iterator - det är lättare att skriva iteratorer från grunden än att bygga på det;
  • codecvt - I själva verket fungerade det mycket dåligt, utskottet efterlyste användningen av specialiserade bibliotek;
  • shared_ptr::unique() - på grund av opålitlighet i en flertrådig miljö.

De lovar att ta bort dem helt i C++20.

Förbud relaterade till nya C++17-funktioner

  • result_of→ invoke_resultär en enklare syntax baserad på C++11-typinferens [15] ;
  • bool uncaught_exception()→ int uncaught_exceptions() - i behandlingen av ett undantag kan systemet kasta ett annat, så att flera undantag kan "hänga" obehandlat. Att kontrollera hur många av dem som fanns i konstruktorn och hur många som fanns i destruktorn är en mer tillförlitlig och "fri" metod ur de tillgängliga bibliotekens synvinkel för att avgöra om ett undantag från förstöraren ska göras eller inte [16] [ 17] [18] .

Borttagna C-biblioteksrubriker

Med övergången till C11, header-filerna <ccomplex>, <cstdalign>, <cstdbool>, <ctgmath>. Filen <ciso646>är inte förbjuden [19] .

autox{}; skapar inte längre en initializer_list

Den universella initialiseraren som läggs till i C++11 int x{};låter dig skapa ett objekt, struktur, array med en syntax. I C++17 är det förtydligat: om det istället för en typ står , autovill användaren skapa ett objekt och ingen initializer_list behövs.

Samtidigt auto x = {1, 2, 3};fortsätter det att skapa: å ena sidan, för kompatibilitet med , å andra sidan finns det [20] [9]for (auto x : {1, 2, 3}) för ett objekt . auto x = 1;

auto x1 = { 3 }; // std::initializer_list<int> auto x2 { 1 , 2 }; // fel nu auto x3 { 3 }; // int

Globala förändringar

Undantagsspecifikationen är nu en del av typsystemet

Funktionerna och  är nu funktioner med olika typer (men kan inte bilda en överbelastad uppsättning). Detta kommer att tillåta API:n att kräva callback som inte ger undantag, samt optimera koden för inga [21] . void f() noexcept(true);void f() noexcept(false);

Ny överjusterad

C++11 introducerade möjligheten att skapa datastrukturer vars anpassning är större än teoretisk. Denna möjlighet togs upp av den nya operationen [22] .

klass alignas ( 16 ) float4 { flyta f [ 4 ]; }; float4 * p = new float4 [ 1000 ];

Det var en överbelastning av den nya operatören med en extra parameter för att korrekt allokera ett överjusterat objekt i minnet.

Obligatorisk omhändertagande av kopiering

Innebörden av prvalue-begreppet har ändrats: nu är det bara en initialisering.

Medan koden SomeType a = 10;fortfarande kräver både konstruktorn och =-operatorn, är det garanterat bara konstruktorn att anropas.

Det betyder att funktioner kan returnera typer som inte kan kopieras och flyttas.

Striktare utvärderingsordning

Nu utvärderas operationerna a.b, a->b, a->*b, a(b1, b2, b3), b += a(och analoger för andra operationer), a[b], a << boch a >> bi ordningen a → b för att hålla biverkningar under kontroll [23] .

Om de anropas som funktioner (till exempel operator += (a, b)), förblir ordningen odefinierad.

Utvidgade konceptet "konstant i mallen"

Det finns mallar som accepterar en konstant.

mall < int N > struct Array { int a [ N ]; };

Vad kan vara ett konstant N, och vad kan inte - förklarat motsatsen. En konstant i en mall kan inte vara en pekare till ett fält, ett temporärt objekt, en strängliteral, ett resultat typeideller en standardvariabel __func__[17] [24] ;

För kan ha början och slutet av olika typer

Nu for (auto v : x)betyder , tillåter början och slutet av olika typer. auto __begin = begin-expr; auto __end = end-expr;

Detta är basen för att iterera genom intervallen, vilket är ett pågående arbete [25] .

Redaktionella ändringar

Konceptet med en "kontinuerlig iterator"

Std::vektor- och std::strängarrayerna hanterar sammanhängande minnesområden. De introducerade begreppet "kontinuerlig iterator" [26] [27] . Begreppsmässigt har ingenting förändrats.

De gav också definitioner till andra begrepp - vidarebefordranreferens , standardmedlemsinitierare , mallformad entitet . Detta är arbete med C++20 -koncept .

Tecken u'x' och U'x' som inte är kodade av ett enda tecken är förbjudna

Tidigare var detta beteende implementeringsdefinierat.

Samtidigt gjorde de "UTF-8-tecken" som har en typ och kan hålla koder från 0 till 127, liknande UTF-8-strängar - tydligen, så att programmet är mindre beroende av lokalinställningarna på datorn [ 17] [28] . char

Tillfälligt inaktiverad memory_order_consume

På grund av otillräcklig semantik förbjöds beställningsmetoden "konsumera" verbalt (utan märket ), vilket krävde användningen av metoden "förvärva". Arbetet med den nya semantiken pågår fortfarande, och kanske kommer förbudet en dag att hävas [29] . [[deprecated]]

I vilket fall som helst, på PowerPC och ARM kommer alla nedladdningar automatiskt att konsumera , men inte alla kommer att förvärva , och konsumtionsmetoden kan spara klockor i plattformsoberoende kod [30] .

Språk

static_assert med ett argument

Om static_assertdet inte fungerar är det inte alltid nödvändigt att berätta för programmeraren vad som är fel - ofta kan han själv räkna ut det utifrån sammanhanget. [31] .

static_assert ( sizeof ( wchar_t ) == 2 );

inline för globala variabler och konstanter

Nu kan du skriva i header-filen och när du inkluderar den här filen i cpp-filer kommer de alla att referera till samma objekt (klasskonstruktorn kommer inte att anropas upprepade gånger för varje cpp-fil, till skillnad från eller ), inline const ClassName INSTANCE_NAMEconst ClassName INSTANCE_NAMEstatic const ClassName INSTANCE_NAME

Nya standardkommentarer

  • [[fallthrough]]: i en av operatörssektionerna switch"faller vi igenom" avsiktligt till nästa. Möjlig implementering av Duff-enheten
int n = ( antal + 7 ) / 8 ; om ( ! räkna ) returnera ; switch ( räkning % 8 ) { fall 0 : gör { * till = * från ++ ; [[ genomgång ]]; fall 7 : * till = * från ++ ; [[ genomgång ]]; fall 6 : * till = * från ++ ; [[ genomgång ]]; fall 5 : * till = * från ++ ; [[ genomgång ]]; fall 4 : * till = * från ++ ; [[ genomgång ]]; fall 3 : * till = * från ++ ; [[ genomgång ]]; fall 2 : * till = * från ++ ; [[ genomgång ]]; fall 1 : * till = * från ++ ; } while ( -- n > 0 ); }
  • [[nodiscard]]: att anropa en funktion som en procedur anses vara ett fel - till exempel är det en "ren" funktion som string::empty()[32] vars enda jobb är att returnera ett värde, eller ett objektprotokoll kräver att något görs med det returnerade värdet, som i unique_ptr::release(). I den senare C++20- standarden blev det möjligt att ange en orsak till att ett anrop misslyckades.
class SmartPtr { // egen implementering av unique_ptr public : /// Överför ett hanterat objekt till manuell kontroll /// @return a pointer to a managed object [[ nodiscard ]] Payload * release (); }; SmartPtr p ; Nyttolast * data = p . release (); // korrekt användning av en smart pekare radera data ; sid . release (); // varning: ignorerar returvärdet för 'SmartPtr::release()', deklarerat med attributet nodiscard ( void ) p . release (); // så här tystar de varningen
  • [[maybe_unused]]: i ett av kompileringslägena ( Windows / POSIX , debug/release) används inte detta eller det elementet, och detta är inte ett fel.
// QString är alltid UTF-16 och wstring är OS-beroende mall < int Sz > void append ( QString & s , unsigned long ch ); // Windows-version, wstring = UTF-16- mall <> [[ maybe_unused ]] inline void append < 2 > ( QString & s , unsigned long ch ) { s . append ( static_cast < uint16_t > ( ch ); } // POSIX version, wstring = UTF-32 mall <> [[ kanske_unused ]] void bifoga < 4 > ( QString & s , unsigned long ch ) {} // kodning av kodposition i UTF-16, utelämna för korthets skull std :: wstring s = L " \U0001F60E " ; // smiley med glasögon QString r ; // För korthetens skull gör vi en exakt kopia och sådan komplex kod behövs inte. // Men ibland behövs det i någon form av bearbetning - till exempel tecken som inte undkommer. för ( auto c : s ) append < sizeof ( c ) > ( r , c ); Eller parametern används inte avsiktligt, utan namnet lämnas för dokumentationsändamål. klass ISoccerSeason { // offentligt gränssnitt : /// @pre båda lagen deltar den här säsongen. /// @return true om en match spelas mellan hemma- och bortalag /// @warning Under en typisk fotbollssäsong kommer båda lagen att spela mot både hemma- och bortalag. virtual bool doTeamsPlay ([[ maybe_unused ]] const Team & home , [[ maybe_unused ]] const Team & away ) const { return true ; } virtuell ~ ISoccerSeason () = standard ; };

Använda typnamn i kapslade mallar

Fel i C++-språket: i mallar typenameoch på classvissa ställen inte utbytbara [33] .

mall < mall < typnamn > klass X > struct C ; // OK mall < mall < typnamn > typnamn X > struct D ; // kompilerar inte

Båda nyckelorden förklaras uttryckligen utbytbara.

Strukturell länkning

Ett nytt sätt att deklarera variabler för att packa upp komplexa objekt har dykt upp, kallat strukturell bindning [34] .

auto [ place , wasInserted ] = någon Karta . emplace ( nyckel , värde );

Fungerar för par, tuplar och andra typer där . std::get

Namnutrymme A::B post

Definition av kapslade namnområden: [9] [35] namespace A::B {} som förkortning för namespace A { namespace B {} };

Anteckningar för namnutrymmen och uppräknade element

Till exempel:

enum klass TriBool { NEJ , kanske , JA _ NN [[ kanske_oanvänd ]], OSPECIFIERAD [[ utfasad ( "Omdöpt till KANSKE" )]] = KANSKE }; constexpr int TriBool_N = static_cast < int > ( TriBool :: NN ); const char * triBoolNames [ TriBool_N ] = { "nej" , "kanske" , "ja" };

Det finns inget deklarerat mål ännu [17] [36] , men detta kommer att tillåta kompilatorutvecklare att komma med ett - till exempel deklarera att NN-elementet är speciellt och inte behöver tilldelas variabler, bearbetade i switch.

Om vid kompilering

SFINAE - konceptet gjorde det möjligt att göra en enkel mall enable_ifsom ger olika funktionalitet för olika typer, men ger tung kod. I C++17 kan du förenkla programmet: operatorn if constexpr(expression)instansierar koden om uttrycket inom parentes är sant [37] .

mall < classT > _ constexpr T absolut ( T arg ) { returnera arg < 0 ? - arg : arg ; } mall < classT > _ constexpr auto precision_threshold = T ( 0,000001 ); mall < classT > _ constexpr bool close_enough ( T a , T b ) { if constexpr ( is_floating_point_v < T > ) // << !! returnera absolut ( a - b ) < precision_threshold < T > ; annan returnera a == b ; }

I det här fallet ser vi till att skillnaden mellan bråktal är liten, och heltal kontrolleras helt enkelt för likhet.

Förenklad syntax för binär operation i variabelmallar

Packade uttryck [17] [38] :

mall < typnamn ... As > bool foo ( As ... args ) { return ( args && ...); }

Hexadecimal representation av bråktal

Hexadecimal mantissa och decimal exponent: 0xC.68p+2, 0x1.P-126, liknande substitution %a. C har stödt denna syntax sedan version 99 [39] .

Lokal variabelinitiering i if/switch

I likhet med att initiera lokala variabler i for, gör koden mer kompakt [40] .

if ( auto it = m . hitta ( nyckel ); det != m . slut ()) returnera det -> sekund ;

Använda i attribut

// Var ogiltig f () { [[ rpr :: kärna , rpr :: target ( cpu , gpu )]] // upprepa do_task (); } // Blev ogiltig f () { [[ genom att använda rpr : kärna , mål ( cpu , gpu )]] göra_uppgift (); }

Typlösa parametrar i mallar

Låter dig ställa in mallparametrar av valfri typ via [41] . auto

mall < auto X > struct B { static constexpr auto value = X ; }; B < 5 > b1 ; // OK: mallparametertypen är int B < 'a' > b2 ; // OK: mallparametertypen är char B < 2,5 > b3 ; // fel: mallparametertypen kan inte vara dubbel

Fångar lambdaobjekt *detta

var :. Det blev: [42] . [self = *this]{ self.f(); }[*this]{ f(); }

Du kan initiera en enumklass med ett nummer

enum classibland används för att göra en annan heltalstyp inte kompatibel med någonting. Nu kan variabler av denna typ initieras med siffror [43]

enum class Handle : intptr_t { INVALID = 0 }; Handtag h { 42 }; Handtag h = 42 ; // förbjuden

Bibliotek

Mindre förbättringar av biblioteket

  • Icke-konstant överbelastning string::data. Används för att anropa lågnivåsträngsfunktioner som tar en bit minne av en viss längd och fyller den med tecken (till exempel WinAPI ). Före C++11 användes det const_cast<char*>(x.data()), före C++17 var det &x.front().
  • emplace_backett element returnerar en referens. Låter dig skriva något så här:
v . emplace_back ( "alfa" , "bravo" ). göra något ();
  • C-standardbiblioteket har uppdaterats från C99 till C11 [44] .
  • Funktioner std::size(x), std::begin(x), std::end(x), std::empty(x). Tillåter dig att skriva gemensam boilerplate-kod för STL-behållare och arrayer [26] [45] . Dessutom är std:: storlek en nödvändig funktion, som ofta skrevs på egen hand med fel.
  • Tillagd partiell specialisering [46]bool_constant<bool B> = integral_constant<bool, B>;
  • Tillagda egenskapsfunktioner för SFINAE : , , , , (sammansatt typ), (trivialt kopieringsbart objekt och alla två objekt med samma värde har samma interna representation).is_swappableis_nothrow_swappableis_swappable_withis_nothrow_swappable_withis_aggregatehas_unique_object_representations
  • Utökat bibliotek för att arbeta med oinitierat minne. Det finns funktioner , , , , , samt deras versioner för n element.uninitialized_default_constructuninitialized_value_constructuninitialized_movedestroydestroy_at
  • Ny mall . Förenklar skapandet av SFINAE- mallar som kan utökas om typ T finns [47] .void_t<T> = void
  • För tilläggsversion med sökobjekt. Det finns tre sökare som standard: Protozoan, Boyer-Moore och Boyer-Moore-Horspool .std::search
  • Den nya funktionen initierar typ T med data från en tupel.make_from_tuple
  • Den nya konstanten avgör om atomvariabeln är icke-blockerande .atomic::is_always_lock_free
  • Tillagda funktioner för avrundning uppåt, nedåt och till närmaste .chrono
  • Vi lade till funktionerna att ta bort ( ) och extrahera ( ) element.map/setmergeextract
  • Tillagd typ .shared_ptr<T>::weak_type = weak_ptr<T>
  • I vissa fall kan tilldelare ha en ofullständig typ. Nu rekursiva strukturer som . Stora kompilatorer har stött detta under lång tid, det återstår bara att specificera det.struct X { std::vector<X> data; };
  • Lade till implicita konstruktörer till och .pairtuple
  • unique_ptr/shared_ptrkan arbeta med arrayer i C-stil ( ). I C++14 krävdes det att dra in rätt raderingsfunktion ( ).shared_ptr<string[]>(new string[n])shared_ptr<string[]>(new string[n], default_delete<string[]>() )
  • Arbetet [48] [49] har förfinats .common_type

Ny typ std::string_view

Det händer ofta att du behöver skicka en oförändrad sträng till en annan kodsektion, detta kan göras med följande metoder:

void doSmth ( const char * s ); // vad händer om det finns ett nolltecken i strängen? Ja, och insidan av funktionen blir felaktig void doSmth ( const std :: string & s ); // vad händer om strängen inte är en sträng och vi måste allokera minne?

C++17 introducerade en typ string_view —en sträng som bara har en pekare och en längd, inget ägande, ingen minneshantering och ingen ens avslutande null—och så den har inte en c_str(). Endast kanter (början/längden) kan ändras, inte tecken. Programmerarens jobb är att se till att objektet inte överlever minnesbufferten där strängen är lagrad, och att skicka parametrar är en stor användning för det. Objektet string_viewär mycket litet (2 bitars maskin) och bör skickas med värde snarare än genom referens.

string_viewi sig är en abstraktion - den abstraherar bort stränglagringsmetoden, som bara kräver en sak - att textdata är konsekutiva byte i minnet. Endast komplexa ovanliga strukturer (till exempel sele/rep ) lagrar slumpmässiga strängar. Och alla andra - och , och , och olika typer av arrayer - konverteras till . stringconst char*string_view

Cache radstorlek

Det finns två nya konstanter, hardware_constructive_interference_sizeoch hardware_destructive_interference_size. Således kan användaren undvika falsk delning (destruktiv störning) och förbättra lokalitet (konstruktiv störning).

struct keep_apart { alignas ( hardware_destructive_interference_size ) atomic < int > cat ; alignas ( hardware_destructive_interference_size ) atomic < int > dog ; // katt är långt ifrån hund, de kan ändras från olika trådar. }; struct -together { atomär < int > hund ; int valp ; }; struct kennel { //... alignas ( storlek på ( tillsammans )) tillsammans pack ; //... }; static_assert ( sizeof ( tillsammans ) <= hardware_constructive_interference_size ); // se till att tillsammans är en cache-rad.

Teoretiskt sett borde båda konstanterna vara desamma, men för att stödja heterogena arkitekturer beslöt man att göra två konstanter. [femtio]

Den nya shared_mutex-typen

En mutex som låter dig läsa parallellt och skriva till en [51] . Blockerare för det kallas shared_lockoch unique_lock.

Automatisk identifiering av containerparametertyp

Funktioner dök upp i biblioteket, de så kallade avdragsguiderna , så att du kan göra detta:

std :: par p ( 2 , 4,5 ); // ett std :: vektor < int > v = { 1 , 2 , 3 , 4 }; std :: vektor x ( v.begin ( ), v. end ( ) ) ; // 2

Nya funktioner för att infoga i en associativ array med en icke-upprepad nyckel

För std::mapoch std::unordered_maptvå nya funktioner har lagts till [52] .

#include <iostream> #inkludera <karta> klass Par { offentliga : int värde1 , värde2 ; Par () : värde1 ( 0 ), värde2 ( 0 ) {} explicit par ( int aValue1 ) : värde1 ( aValue1 ), värde2 ( 0 ) {} Par ( int aValue1 , int aValue2 ) : värde1 ( aValue1 ), värde2 ( aValue2 ) {} }; int main () { std :: map < std :: sträng , par > m ; // C++11 m [ "a" ] = Par ( 3 , 4 ); m . emplace ( "a" , 1 ); // Par skapas alltid // C++17 m . insert_or_assign ( "a" , Par ( 3 , 4 )); m . try_emplace ( "a" , 1 ); // Par skapas vid behov returnera 0 ; }

Nya matematiska funktioner

Icke-standardiserade matematiska funktioner har introducerats i std-namnutrymmet: beta, , , , , , , , , , , [53] [54] . Det finns inga utanför std (in ). cyl_bessel_i/j/kcyl_neumann[comp_]ellint_1/2/3expinthermite[assoc_]laguerre[assoc_]legendreriemann_zetasph_besselsph_legendresph_neumannmath.h

Från den första meningen (2010): "Vi hoppas att antagandet av detta förslag kommer att skicka ett meddelande till de olika datorcommunityerna att C++, trots folklig uppfattning, också är ganska lämplig för deras bransch." Då blev han inte antagen. Nu har de stora biblioteksleverantörerna ( Dinkumware , Boost , GCC ) redan dessa funktioner.

Lade också till beräkning av GCD [55] och LCM [56] , funktionen av reduktion till intervallet ( ) [57] , tredimensionell hypotenusa . clamphypot(x, y, z)

Filsystembibliotek

Ett filsystemsbibliotek baserat på boost::filesystemlåter dig: [58]

  • automatisk internationalisering av filnamn beroende på operativsystemets funktioner. Biblioteket döljer kodningen som det fungerar i och konverterar själv namnen till det önskade - åtminstone till den lokaldefinierade enbyte och olika Unicode-varianter;
  • kataloggenomgång (inklusive rekursiv);
  • definition av filtyper (vanlig, katalog , socket ...);
  • dela upp sökvägen till filen i komponenter: enhet, katalog, namn och tillägg;
  • skapa kataloger, kopiera filer, ta bort kataloger och filer (inklusive rekursiva);
  • få namn på temporära filer .

Variabeltyper

Det fanns en klass som kunde innehålla data av vilken typ som helst [59] [60] . Implementeringar krävs för att passa små objekt utan att allokera minne. Funktionen kräver en exakt matchning av typen och ger inget om den är inuti . std::anyanyany_castany_cast<double>int

std :: cout << std :: boolalpha ; std :: any a = 1 ; std :: cout << a . typ (). namn () << ": " << std :: any_cast < int > ( a ) << std :: endl ; a = 3,14 ; std :: cout << a . typ (). namn () << ": " << std :: any_cast < double > ( a ) << std :: endl ; a = sant ; std :: cout << a . typ (). namn () << ": " << std :: any_cast < bool > ( a ) << std :: endl ; // i: 1 // d: 3,14 // b: sant

Det finns också enklare std::variant<int, bool, double>och std::optional<T>.

Funktioner för konvertering av tal-till-text på låg nivå

En känd nackdel med C++: för lågnivåkonvertering av siffror till text utan minnesallokering måste du köra en tung och opålitlig sprintfsådan, och den inbyggda konverteringen av text till ett nummer kvar med C är ganska opålitlig.

Nu finns det inbyggda lokaloberoende superhastigheter from_chars[61] och to_chars[62] . De är utformade på ett sådant sätt att de inte kräver (och producerar inte) en slutnolla och kan fungera till exempel på string_view. På grund av deras begränsningar och lokala oberoende är de främst avsedda för JSON och XML , där det krävs en enorm hastighet.

Ny typ polymorphic_allocator

STL-datastrukturer ( strängar , vektorer , etc.) innehåller en mallparameter - en minnesallokator. Denna allokator fungerar som ett generiskt programmeringskoncept , inte som ett objektorienterat gränssnitt: allokering av minne på heapen och poolen resulterar i olika inkompatibla typer. En klass  är en standardstart för en sällsynt uppgift: beroende på vissa förhållanden, allokera minne antingen på högen eller i poolen. polymorphic_allocator

I sig är det  inte ett gränssnitt, men det är associerat med ett gränssnitt . polymorphic_allocatormemory_resource

Ny mall std::invoke

Tillåter konsekvent anrop av funktioner, objekt med ()-operatorn ( functors ) och lambda-objekt [63] . Även lagt till funktioner , , . is_invocableis_invocable_rinvoke_result

Parallella versioner av STL-algoritmer

För 69 algoritmer från , och parallella versioner har uppfunnits [64] [65] [66] . <algorithm><numeric><memory>

Se även

Länkar

  • Utkast till standard, N4659 , daterad 2017-03-21

Anteckningar

  1. ISO/IEC 14882:2017 . Hämtad 4 december 2017. Arkiverad från originalet 17 maj 2013.
  2. Nya milstolpar: C++17 nästan komplett med funktioner, andra omgången av TS:er nu under utveckling . Hämtad 28 mars 2016. Arkiverad från originalet 8 september 2020.
  3. N3981: Ta bort trigrafer??! (Richard Smith) (6 maj 2014). Hämtad 28 mars 2016. Arkiverad från originalet 9 juli 2018.
  4. IBM kommenterar att förbereda sig för en Trigraph-adverse future i C++17 Arkiverad 11 september 2018 på Wayback Machine , IBM paper N4210, 2014-10-10.
  5. Ta bort föråldrad användning av registrets nyckelord . Hämtad 20 augusti 2018. Arkiverad från originalet 14 september 2017.
  6. Ta bort föråldrad operator++(bool) . Hämtad 20 augusti 2018. Arkiverad från originalet 11 september 2017.
  7. Ta bort föråldrade undantagsspecifikationer från C++17 . Hämtad 20 augusti 2018. Arkiverad från originalet 13 september 2017.
  8. N4190: Ta bort auto_ptr, random_shuffle() och gamla <funktionella> grejer (Stephan T. Lavavej) . Hämtad 28 mars 2016. Arkiverad från originalet 20 oktober 2017.
  9. 1 2 3 Uppdateringar av min reserapport . Datum för åtkomst: 28 mars 2016. Arkiverad från originalet 19 mars 2015.
  10. Ta bort föråldrade iostreams-alias . Hämtad 20 augusti 2018. Arkiverad från originalet 22 augusti 2017.
  11. Ta bort allokeringsstöd i standard::funktion (rev 1) . Hämtad 20 augusti 2018. Arkiverad från originalet 17 september 2017.
  12. Utfasning av Vestigial Library Parts i C++17 . Hämtad 20 augusti 2018. Arkiverad från originalet 13 september 2017.
  13. Utfasar <codecvt> . Hämtad 20 augusti 2018. Arkiverad från originalet 16 september 2017.
  14. Förslag till resolution för CA 14 (shared_ptr use_count/unique) . Hämtad 20 augusti 2018. Arkiverad från originalet 7 juli 2017.
  15. Löser GB 55, US 84, US 85, US 86 . Hämtad 20 augusti 2018. Arkiverad från originalet 5 juli 2017.
  16. N4259: Ordalydelse för std::uncaught_exceptions (Herb Sutter) . Hämtad 28 mars 2016. Arkiverad från originalet 29 november 2014.
  17. 1 2 3 4 5 Nya grundläggande språkdokument antagna för C++17 . Hämtad 28 mars 2016. Arkiverad från originalet 27 april 2015.
  18. Källa . Hämtad 31 maj 2022. Arkiverad från originalet 16 november 2017.
  19. C++17 bör referera till C11 istället för C99 . Hämtad 20 augusti 2018. Arkiverad från originalet 13 september 2017.
  20. N3922: Nya regler för automatiskt avdrag från braced-init-list (James Dennett) . Hämtad 28 mars 2016. Arkiverad från originalet 10 augusti 2015.
  21. Låt undantagsspecifikationer vara en del av typsystemet . Hämtad 20 augusti 2018. Arkiverad från originalet 12 september 2017.
  22. Dynamisk minnesallokering för överjusterade data . Hämtad 20 augusti 2018. Arkiverad från originalet 8 september 2017.
  23. [ http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0145r3.pdf Ordning för raffinering av uttrycksutvärdering för idiomatisk C++] . Hämtad 23 augusti 2018. Arkiverad från originalet 26 augusti 2018.
  24. N4268: Tillåt konstant utvärdering av alla mallargument som inte är av typen (Richard Smith) . Hämtad 28 mars 2016. Arkiverad från originalet 12 mars 2016.
  25. Generalisering av räckviddsbaserad för loop . Hämtad 23 augusti 2018. Arkiverad från originalet 5 oktober 2017.
  26. 1 2 Nya standardbibliotekspapper antagna för C++17 . Hämtad 28 mars 2016. Arkiverad från originalet 29 november 2014.
  27. N4284: Sammanhängande iteratorer (Jens Maurer) . Hämtad 28 mars 2016. Arkiverad från originalet 29 november 2014.
  28. N4267: Lägga till bokstaver i u8-tecken (Richard Smith) . Hämtad 28 mars 2016. Arkiverad från originalet 28 oktober 2015.
  29. Avskräcka tillfälligt memory_order_consume . Hämtad 20 augusti 2018. Arkiverad från originalet 16 januari 2018.
  30. Syftet med memory_order_consume i C++11 . Hämtad 15 augusti 2019. Arkiverad från originalet 11 november 2019.
  31. N3928: Extending static_assert, v2 (Walter E. Brown) . Hämtad 28 mars 2016. Arkiverad från originalet 11 augusti 2015.
  32. Därför klagade författarna till PVS-Studioclear() ofta på ett fel: programmeraren skrev empty().
  33. N4051: Tillåt typnamn i en mall-mallparameter (Richard Smith) . Hämtad 28 mars 2016. Arkiverad från originalet 11 augusti 2015.
  34. Strukturerad bindande förklaring (sedan C++17) Arkiverad 8 september 2020 på Wayback Machine en.cppreference.com
  35. N4230: Definition av kapslad namnområde (Robert Kawulak, Andrew Tomazos) . Hämtad 28 mars 2016. Arkiverad från originalet 3 augusti 2015.
  36. N4266: Attribut för namnutrymmen och uppräknare (Richard Smith) . Datum för åtkomst: 28 mars 2016. Arkiverad från originalet 6 mars 2016.
  37. constexpr if: En något annorlunda syntax . Hämtad 20 augusti 2018. Arkiverad från originalet 7 oktober 2017.
  38. N4295: Vikningsuttryck (Andrew Sutton, Richard Smith) . Hämtad 28 mars 2016. Arkiverad från originalet 4 april 2015.
  39. Hexadecimala flytande bokstaver för C++ . Hämtad 12 juni 2019. Arkiverad från originalet 22 augusti 2017.
  40. Urvalssatser med initialiserare . Hämtad 12 juni 2019. Arkiverad från originalet 6 oktober 2017.
  41. Deklarera icke-typ mallparametrar med auto . Hämtad 7 augusti 2020. Arkiverad från originalet 16 september 2017.
  42. Lambdafångst av *this by Value as [=,*this ] . Hämtad 7 augusti 2020. Arkiverad från originalet 22 augusti 2017.
  43. Konstruktionsregler för enumklassvärden . Hämtad 7 augusti 2020. Arkiverad från originalet 9 december 2017.
  44. C++17 bör referera till C11 istället för C99 . Hämtad 18 december 2016. Arkiverad från originalet 13 november 2016.
  45. N4280: Icke-medlemsstorlek() och mer (Riccardo Marcangelo) . Tillträdesdatum: 28 mars 2016. Arkiverad från originalet 9 mars 2015.
  46. Ordalydelse för bool_constant, revision 1 . Hämtad 1 januari 2020. Arkiverad från originalet 14 oktober 2017.
  47. Arkiverad kopia . Hämtad 1 januari 2020. Arkiverad från originalet 28 augusti 2017.
  48. Arkiverad kopia . Hämtad 1 januari 2020. Arkiverad från originalet 10 oktober 2017.
  49. Arkiverad kopia . Hämtad 1 januari 2020. Arkiverad från originalet 5 juli 2017.
  50. P0154R1 constexpr std::hardware_{constructive,destructive}_interference_size .
  51. std::shared_mutex - cppreference.com . Hämtad 30 augusti 2019. Arkiverad från originalet 30 augusti 2019.
  52. Förbättrat insättningsgränssnitt för std::{unordered_,}map (reviderad) . Hämtad 28 mars 2016. Arkiverad från originalet 27 april 2015.
  53. Arkiverad kopia . Hämtad 20 augusti 2019. Arkiverad från originalet 17 september 2019.
  54. Matematiska specialfunktioner för C++17, v5 . Hämtad 28 mars 2016. Arkiverad från originalet 5 april 2016.
  55. std::gcd - cppreference.com . Hämtad 30 augusti 2019. Arkiverad från originalet 28 mars 2019.
  56. std::lcm - cppreference.com . Hämtad 30 augusti 2019. Arkiverad från originalet 28 mars 2019.
  57. std::clamp - cppreference.com . Hämtad 30 augusti 2019. Arkiverad från originalet 30 augusti 2019.
  58. Filsystembiblioteksförslag (Beman Dawes) . Hämtad 28 mars 2016. Arkiverad från originalet 20 juli 2016.
  59. C++ Extensions for Library Fundamentals, version 2, Working Draft . Hämtad 30 augusti 2019. Arkiverad från originalet 25 augusti 2019.
  60. std::any - cppreference.com . Hämtad 30 augusti 2019. Arkiverad från originalet 30 augusti 2019.
  61. std::from_chars - cppreference.com . Hämtad 30 augusti 2019. Arkiverad från originalet 30 augusti 2019.
  62. std::to_chars - cppreference.com . Hämtad 30 augusti 2019. Arkiverad från originalet 30 augusti 2019.
  63. Ett förslag om att lägga till mall för anropsfunktion (Revision 1) . Hämtad 1 januari 2020. Arkiverad från originalet 6 oktober 2017.
  64. Tillägg för parallellism - cppreference.com . Hämtad 5 februari 2021. Arkiverad från originalet 12 november 2020.
  65. Parallellism TS bör standardiseras . Hämtad 28 mars 2016. Arkiverad från originalet 5 april 2016.
  66. Använda C++17 parallella algoritmer för bättre prestanda | C++ Team Blog . Hämtad 5 februari 2021. Arkiverad från originalet 24 januari 2021.