C++17

Versiunea actuală a paginii nu a fost încă examinată de colaboratori experimentați și poate diferi semnificativ de versiunea revizuită pe 5 mai 2021; verificările necesită 17 modificări .

C++17 (cunoscut și ca C++1z) este numele versiunii ISO /IEC a standardului C++. Specificațiile pentru C++17 au fost publicate în decembrie 2017 [1] [2] .

Valoarea constantei __cplusplusa devenit 201703L, aceasta este folosită pentru compilarea condiționată .

Eliminat sau interzis

Trigrafele eliminate

Trigrafele au fost folosite pentru mașini cu codare non-standard și/sau tastaturi limitate. Înapoi la sfârșitul anilor 80, odată cu răspândirea codificărilor pe 8 biți și a tastaturilor ieftine cu membrană de cauciuc , trigrafele și-au pierdut de fapt sensul, iar treizeci de ani mai târziu au fost în mod natural excluse [3] [4] .

// Următoarea linie va fi executată??????????????????/ a ++ ; /* cu trigrafe această linie este comentată - trigraf ??/ este echivalent cu \ */

S-a eliminat cuvântul cheie de înregistrare

Limbajul C era un „asamblator portabil”: făcea posibilă realizarea de programe rapide care se compila pe diferite computere și folosea, de asemenea, utilitare de asamblare ( linker , bibliotecar). Concepte precum „ fișier antet ” și „ unitate de traducere ” sunt ecouri ale acelor vremuri.

Cuvântul registera fost asociat inițial cu optimizarea manuală a programului. Compilatoarele moderne „sub capotă” fac un număr mare de optimizări, iar un astfel de control manual pare redundant. Înapoi în C++11, cuvântul a fost declarat nedorit. Cuvântul este încă rezervat și poate fi folosit într-o zi în alt scop - ca în C++11 [5] . auto

S- a eliminat operația ++ pentru bool

Operația este evident nesigură și este interzisă în C++98 [6] . Operația --lipsește.

S-au eliminat excepțiile declarate

Excepțiile declarate void f() throw(A, B, C);, găsite în Java , de exemplu, fac mai mult rău decât bine. Interzis în C++11, eliminat în C++17. A rămas throw()ca sinonim pentru noexcept(true)[7] .

Au fost eliminate tipurile și funcțiile care au fost înlocuite (și interzise) în C++11

Printre acestea se numără adaptoare funcționale std::auto_ptrvechi [8] [9] . std::random_shuffle

În schimb, unique_ptr, shuffleși noi șabloane de funcții bazate pe function/ sunt utilizate bind. Se pretinde că orice cod activat auto_ptrpoate fi convertit mecanic în unique_ptr, cu o simplă adăugare std::moveîn cazul în care există un transfer de proprietate.

Părțile separate iostreaminterzise în C++98 [10] au fost, de asemenea, eliminate .

S-au eliminat constructorii pentru funcția std:: care a luat un alocător

Cinci supraîncărcări în total, inclusiv aceasta

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

Din cauza semanticii de neînțeles și a dificultăților de implementare, acestea au fost înlăturate fără interdicție prealabilă [11] .

Caracteristicile extrem de rare ale bibliotecii standard sunt interzise

Mai multe caracteristici rare ale bibliotecii standard sunt interzise: [12] [13] [14]

  • allocator<void> - s-a dovedit a fi nerevendicat;
  • unele dintre funcții allocator sunt duplicate de șablon allocator_traits;
  • raw_storage_iterator - nu apelează la constructori și, prin urmare, este limitat în aplicare;
  • get_temporary_buffer - are capcane neevidente;
  • is_literal_type - inutil pentru codul generic, dar lăsat atâta timp cât există un concept de „tip literal” în C++;
  • iterator - este mai ușor să scrii iteratoare de la zero decât să construiești pe ei;
  • codecvt - de fapt, a funcționat foarte prost, comisia a cerut folosirea bibliotecilor de specialitate;
  • shared_ptr::unique() - din cauza nefiabilității într-un mediu cu mai multe fire.

Ei promit să le elimine complet în C++20.

Interdicții legate de noile funcții C++17

  • result_of→ invoke_resulteste o sintaxă mai simplă bazată pe inferența de tip C++11 [15] ;
  • bool uncaught_exception()→ int uncaught_exceptions() - în procesarea unei excepții, sistemul poate arunca o alta, astfel încât mai multe excepții să se poată „bloca” netratate. Verificarea câte dintre ele au fost în constructor și câte au fost în destructor este o metodă mai fiabilă și „liberă” din punctul de vedere al bibliotecilor disponibile pentru a determina dacă să se arunce sau nu o excepție de la destructor [16] [ 17] [18] .

S- au eliminat antetele bibliotecii C

Odată cu trecerea la C11, fișierele de antet <ccomplex>, <cstdalign>, <cstdbool>, <ctgmath>. Dosarul <ciso646>nu este interzis [19] .

autox{}; nu mai creează o listă de inițializare

Inițializatorul universal adăugat în C++11 int x{};vă permite să creați un obiect, o structură, o matrice cu o singură sintaxă. În C++17, este clarificat: dacă în loc de un tip stă , autoutilizatorul dorește să creeze un obiect și nu este nevoie de initializer_list.

În același timp , auto x = {1, 2, 3};continuă să creeze: pe de o parte, pentru compatibilitate cu , pe de altă parte, există [20] [9]for (auto x : {1, 2, 3}) pentru un obiect . auto x = 1;

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

Modificări globale

Specificația de excepție face acum parte din sistemul de tip

Funcțiile și  sunt acum funcții cu tipuri diferite (dar nu pot forma un set supraîncărcat). Acest lucru va permite API-ului să solicite callback -uri care nu aruncă excepții, precum și să optimizeze codul pentru niciunul [21] . void f() noexcept(true);void f() noexcept(false);

Nou supraaliniat

C++11 a introdus capacitatea de a crea structuri de date a căror aliniere este mai mare decât cea teoretică. Această posibilitate a fost preluată de noua operațiune [22] .

class aliñas ( 16 ) float4 { float f [ 4 ]; }; float4 * p = float4 nou [ 1000 ];

A existat o supraîncărcare a noului operator cu un parametru suplimentar pentru a aloca corect un obiect supraaliniat în memorie.

Dispunerea obligatorie a copierii

Sensul conceptului prvalue a fost schimbat: acum este doar o inițializare.

Deși codul SomeType a = 10;necesită încă atât constructorul, cât și operatorul =, se garantează că numai constructorul va fi apelat.

Aceasta înseamnă că funcțiile pot returna tipuri care nu pot fi copiate și mutate.

Ordine de evaluare mai strictă

Acum operațiile a.b, a->b, a->*b, a(b1, b2, b3), b += a(și analogii pentru alte operații), a[b], a << bși a >> bsunt evaluate în ordinea a → b pentru a menține efectele secundare sub control [23] .

Dacă sunt apelate ca funcții (de exemplu, operator += (a, b)), ordinea rămâne nedefinită.

S-a extins conceptul de „constant în șablon”

Există șabloane care acceptă o constantă.

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

Ce poate fi o constantă N și ce nu poate - a declarat contrariul. O constantă dintr-un șablon nu poate fi un pointer către un câmp, un obiect temporar, un literal șir, un rezultat typeidsau o variabilă standard __func__[17] [24] ;

Pentru pot avea început și sfârșit de diferite tipuri

Acum for (auto v : x)înseamnă , permițând începutul și sfârșitul diferitelor tipuri. auto __begin = begin-expr; auto __end = end-expr;

Aceasta este baza pentru iterarea prin intervale, ceea ce este un lucru în curs [25] .

Modificări editoriale

Conceptul de „iterator continuu”

Matricele std::vector și std::string se ocupă de regiunile contigue ale memoriei. Au introdus conceptul de „iterator continuu” [26] [27] . Conceptual, nimic nu s-a schimbat.

De asemenea, au dat definiții altor concepte - referință de redirecționare , inițializare implicită a membrilor , entitate șablon . Acesta este lucru pe concepte C++20 .

Caracterele u'x' şi U'x' care nu sunt codificate de un singur caracter sunt interzise

Anterior, acest comportament a fost definit de implementare.

În același timp, au făcut „caractere UTF-8” care au un tip și pot conține coduri de la 0 la 127, similare șirurilor UTF-8 - aparent, astfel încât programul să fie mai puțin dependent de setările locale de pe computer [ 17] [28] . char

Memorie_order_consume dezactivată temporar

Din cauza semanticii inadecvate, metoda de ordonare „consuma” a fost interzisă verbal (fără marcajul ), solicitând utilizarea metodei „dobândiți”. Lucrările la noua semantică sunt încă în desfășurare și, probabil, interdicția va fi ridicată într-o zi [29] . [[deprecated]]

În orice caz, pe PowerPC și ARM , toate descărcările vor consuma automat , dar nu toate vor dobândi , iar metoda consume poate salva ceasurile în codul multiplatform [30] .

Limba

static_assert cu un argument

Dacă static_assertnu funcționează, nu este întotdeauna necesar să-i spuneți programatorului ce este în neregulă - adesea el însuși poate înțelege din context. [31] .

static_assert ( sizeof ( wchar_t ) == 2 );

inline pentru variabile globale și constante

Acum puteți scrie în fișierul antet și când includeți acest fișier în fișierele cpp, toate se vor referi la același obiect (constructorul de clasă nu va fi apelat în mod repetat pentru fiecare fișier cpp, spre deosebire de sau ), inline const ClassName INSTANCE_NAMEconst ClassName INSTANCE_NAMEstatic const ClassName INSTANCE_NAME

Adnotări standard noi

  • [[fallthrough]]: într-una dintre secțiunile operatorului, switch„cădem” în mod intenționat în următoarea. Posibilă implementare a dispozitivului Duff
int n = ( numărare + 7 ) / 8 ; dacă ( ! numără ) întoarce ; comutare ( count % 8 ) { cazul 0 : do { * to = * from ++ ; [[ fallthrough ]]; cazul 7 : * la = * de la ++ ; [[ fallthrough ]]; cazul 6 : * la = * de la ++ ; [[ fallthrough ]]; cazul 5 : * la = * de la ++ ; [[ fallthrough ]]; cazul 4 : * la = * de la ++ ; [[ fallthrough ]]; cazul 3 : * la = * de la ++ ; [[ fallthrough ]]; cazul 2 : * la = * de la ++ ; [[ fallthrough ]]; cazul 1 : * la = * de la ++ ; } în timp ce ( -- n > 0 ); }
  • [[nodiscard]]: apelarea unei funcții ca procedură este considerată o eroare - de exemplu, este o funcție „pură” ca string::empty()[32] a cărei singura sarcină este să returneze o valoare, sau un protocol de obiect necesită să se facă ceva cu valoarea returnată, ca în unique_ptr::release(). În standardul C++20 mai târziu , a devenit posibil să se specifice un motiv pentru care un apel a eșuat.
clasa SmartPtr { // implementare proprie a unique_ptr public : /// Transferă un obiect gestionat la control manual /// @return un pointer către un obiect gestionat [[ nodiscard ]] Payload * release (); }; SmartPtr p ; Sarcina utilă * date = p . eliberare (); // utilizarea corectă a unui pointer inteligent șterge datele ; p . eliberare (); // avertisment: ignorând valoarea returnată a lui „SmartPtr::release()”, declarată cu atributul nodiscard ( void ) p . eliberare (); // așa aduc la tăcere avertismentul
  • [[maybe_unused]]: într-unul dintre modurile de compilare ( Windows / POSIX , debug/release) nu se utilizează acest sau acel element și nu este o eroare.
// QString este întotdeauna UTF-16 și wstring este un șablon dependent de sistemul de operare < int Sz > void append ( QString & s , unsigned long ch ); // Versiunea Windows, wstring = șablon UTF-16 <> [[ maybe_unused ]] inline void append < 2 > ( QString & s , unsigned long ch ) { s . append ( static_cast < uint16_t > ( ch ); } // Versiunea POSIX, wstring = șablon UTF-32 <> [[ maybe_unused ]] void append < 4 > ( QString & s , unsigned long ch ) {} // codificarea poziției codului în UTF-16, omiteți pentru concizie std :: wstring s = L " \U0001F60E " ; // zâmbet cu ochelari QString r ; // Pentru concizie, facem o copie exactă și nu este necesar un astfel de cod complex. // Dar uneori este necesar într-un fel de procesare - de exemplu, caractere nescapate. pentru ( auto c : s ) append < sizeof ( c ) > ( r , c ); Sau parametrul nu este folosit intenționat, dar numele este lăsat în scopuri de documentare. clasa ISoccerSeason { // interfață publică : /// @pre ambele echipe participă în acest sezon. /// @return true dacă se joacă un meci între echipe acasă și oaspeți /// @warning Într-un sezon obișnuit de fotbal, ambele echipe vor juca atât echipe acasă, cât și echipe în deplasare. virtual bool doTeamsPlay ([[ maybe_unused ]] const Team & home , [[ maybe_unused ]] const Team & away ) const { return true ; } virtual ~ ISoccerSeason () = implicit ; };

Utilizarea numelui de tip în șabloanele imbricate

Defect al limbajului C++: în șabloane typenameși în classunele locuri nu sunt interschimbabile [33] .

template < template < typename > class X > struct C ; // OK template < template < typename > typename X > struct D ; // nu se compila

Ambele cuvinte cheie sunt declarate în mod explicit interschimbabile.

Legături structurale

A apărut o nouă modalitate de declarare a variabilelor pentru despachetarea obiectelor complexe, numită legare structurală [34] .

auto [ loc , wasInserted ] = someMap . emplace ( cheie , valoare );

Funcționează pentru perechi, tupluri și alte tipuri în care . std::get

Spațiul de nume A::B intrare

Definiția spațiilor de nume imbricate: [9] [35] namespace A::B {} ca prescurtare pentru namespace A { namespace B {} };

Adnotări pentru spații de nume și elemente enumerate

De exemplu:

clasa enumerare TriBool { NU , poate , DA , NN [[ maybe_unused ]], NESPECIFICAT [[ depreciat ( "Redenumit în MAYBE" )]] = MAYBE }; constexpr int TriBool_N = static_cast < int > ( TriBool :: NN ); const char * triBoolNames [ TriBool_N ] = { "nu" , "poate" , "da" };

Nu există încă un scop declarat [17] [36] , dar acest lucru va permite dezvoltatorilor de compilatori să vină cu unul - de exemplu, să declare că elementul NN este special și nu trebuie să fie atribuit variabilelor, procesate în switch.

Dacă la compilare

Conceptul SFINAE a făcut posibilă realizarea unui șablon simplu enable_ifcare oferă funcționalități diferite pentru diferite tipuri, dar oferă cod greu. În C++17, puteți simplifica programul: operatorul if constexpr(expression)instanțiază codul dacă expresia dintre paranteze este adevărată [37] .

șablon < classT > _ constexpr T absolut ( T arg ) { return arg < 0 ? - arg : arg ; } șablon < classT > _ constexpr auto precision_threshold = T ( 0,000001 ); șablon < classT > _ constexpr bool close_enough ( T a , T b ) { if constexpr ( is_floating_point_v < T > ) // << !! returnează absolut ( a - b ) < prag_precizie < T > ; altfel returnează a == b ; }

În acest caz, ne asigurăm că diferența dintre numerele fracționale este mică, iar numerele întregi sunt pur și simplu verificate pentru egalitate.

Sintaxă simplificată pentru operarea binară în șabloane variabile

Expresii impachetate [17] [38] :

template < typename ... As > bool foo ( As ... args ) { return ( args && ...); }

Reprezentarea hexazecimală a numerelor fracționale

mantisă hexazecimală și exponent zecimal: 0xC.68p+2, 0x1.P-126, similar cu substituția %a. C a suportat această sintaxă încă din versiunea 99 [39] .

Inițializarea variabilelor locale în if/switch

Similar cu inițializarea variabilelor locale în for, face codul mai compact [40] .

if ( auto it = m . find ( key ); it != m . end ()) return it -> second ;

Utilizarea în atribute

// A fost nulă f () { [[ rpr :: kernel , rpr :: target ( cpu , gpu )]] // repeta do_task (); } // A devenit void f () { [[ folosind rpr : kernel , target ( cpu , gpu )]] face_sarcina (); }

Parametri fără tip în șabloane

Vă permite să setați parametrii șablonului de orice tip prin [41] . auto

template < auto X > struct B { static constexpr auto value = X ; }; B < 5 > b1 ; // OK: tipul parametrului șablonului este int B < 'a' > b2 ; // OK: tipul de parametru al șablonului este char B < 2.5 > b3 ; // eroare: tipul de parametru al șablonului nu poate fi dublu

Captură obiect lambda *acest

A fost: . A devenit: [42] . [self = *this]{ self.f(); }[*this]{ f(); }

Puteți inițializa o clasă enumerare cu un număr

enum classuneori folosit pentru a face un alt tip întreg incompatibil cu nimic. Acum variabilele de acest tip pot fi inițializate cu numere [43]

clasa enum Handle : intptr_t { INVALID = 0 }; Mâner h { 42 }; Mâner h = 42 ; // interzis

Biblioteca

Îmbunătățiri minore ale bibliotecii

  • Supraîncărcare non-constantă string::data. Folosit pentru a apela funcții de tip șir de nivel scăzut care iau o bucată de memorie de o anumită lungime și o umplu cu caractere (de exemplu, WinAPI ). Înainte de C++11 a fost folosit const_cast<char*>(x.data()), înainte de C++17 a fost &x.front().
  • emplace_backun element returnează o referință. Vă permite să scrieți ceva de genul acesta:
v . emplace_back ( "alfa" , "bravo" ). face ceva ();
  • Biblioteca standard C a fost actualizată de la C99 la C11 [44] .
  • Funcții std::size(x), std::begin(x), std::end(x), std::empty(x). Vă permite să scrieți cod standard pentru containere și matrice STL [26] [45] . În plus, std:: size este o funcție necesară, care a fost adesea scrisă singură cu erori.
  • Specializare parțială adăugată [46]bool_constant<bool B> = integral_constant<bool, B>;
  • Funcții de proprietate adăugate pentru SFINAE : , , , , (tip compus), (obiect copiabil trivial și orice două obiecte cu aceeași valoare au aceeași reprezentare internă).is_swappableis_nothrow_swappableis_swappable_withis_nothrow_swappable_withis_aggregatehas_unique_object_representations
  • Bibliotecă extinsă pentru lucrul cu memorie neinițializată. Există funcții , , , , , precum și versiunile acestora pentru n elemente.uninitialized_default_constructuninitialized_value_constructuninitialized_movedestroydestroy_at
  • Șablon nou . Simplifică crearea de șabloane SFINAE care pot fi extinse dacă există tipul T [47] .void_t<T> = void
  • Pentru versiunea adăugată cu obiect Finder. Există trei căutări implicite: Protozoan, Boyer-Moore și Boyer-Moore-Horspool .std::search
  • Noua funcție inițializează tipul T cu date dintr-un tuplu.make_from_tuple
  • Noua constantă determină dacă variabila atomică este neblocantă .atomic::is_always_lock_free
  • S-au adăugat funcții pentru rotunjirea în sus, în jos și la cel mai apropiat .chrono
  • Am adăugat funcțiile de eliminare ( ) și extragere ( ) elemente.map/setmergeextract
  • Tip adăugat .shared_ptr<T>::weak_type = weak_ptr<T>
  • În unele cazuri, alocătorii pot avea un tip incomplet. Acum structuri recursive precum . Compilatorii majori au suportat acest lucru de mult timp, rămâne doar să îl specificam.struct X { std::vector<X> data; };
  • S-au adăugat constructori impliciti la și .pairtuple
  • unique_ptr/shared_ptrpoate lucra cu tablouri în stil C ( ). În C++14, era necesar să trageți funcția de ștergere corectă ( ).shared_ptr<string[]>(new string[n])shared_ptr<string[]>(new string[n], default_delete<string[]>() )
  • Lucrarea [48] [49] a fost rafinată .common_type

Tip nou std::string_view

Se întâmplă adesea să trebuiască să treceți un șir neschimbat unei alte secțiuni de cod, acest lucru se poate face folosind următoarele metode:

void doSmth ( const char * s ); // ce se întâmplă dacă există un caracter nul în șir? Da, iar interiorul funcției devine eronat void doSmth ( const std :: string & s ); // ce se întâmplă dacă șirul nu este un șir și trebuie să alocăm memorie?

C++17 a introdus un tip string_view - un șir care are doar un pointer și o lungime, nicio proprietate, nicio gestionare a memoriei și nici măcar nu are terminare - și deci nu are un c_str(). Numai chenarele (început/lungime) pot fi modificate, nu caracterele. Sarcina programatorului este să se asigure că obiectul nu supraviețuiește memoriei tampon în care este stocat șirul, iar trecerea parametrilor este o utilizare excelentă pentru el. Obiectul string_vieweste foarte mic (mașină de 2 biți) și ar trebui să fie transmis mai degrabă prin valoare decât prin referință.

string_viewîn sine este o abstractizare - abstrage metoda de stocare a șirurilor de caractere, necesitând un singur lucru - ca datele text să fie octeți consecutivi în memorie. Doar structurile complexe neobișnuite (de exemplu, praștie/frânghie ) stochează șiruri aleatorii. Și toate celelalte - și , și , și diferite tipuri de matrice - sunt convertite în . stringconst char*string_view

Dimensiunea liniei cache

Există două constante noi hardware_constructive_interference_sizeși hardware_destructive_interference_size. Astfel, utilizatorul poate evita partajarea falsă (interferență distructivă) și poate îmbunătăți localitatea (interferență constructivă).

struct keep_apart { aliñas ( hardware_destructive_interference_size ) atomic < int > cat ; aliñas ( hardware_destructive_interference_size ) atomic < int > dog ; // pisica este departe de câine, pot fi schimbate din fire diferite. }; struct -together { atomic < int > câine ; int catelus ; }; struct kenel { //... aliñas ( sizeof ( together )) together pack ; //... }; static_assert ( sizeof ( împreună ) <= hardware_constructive_interference_size ); // asigurați-vă că împreună există o linie de cache.

Teoretic, ambele constante ar trebui să fie aceleași, dar pentru a suporta arhitecturi eterogene, s-a decis să se facă două constante. [cincizeci]

Noul tip shared_mutex

Un mutex care vă permite să citiți în paralel și să scrieți la unul [51] . Blocanții pentru aceasta sunt numite shared_lockși unique_lock.

Detectarea automată a tipului de parametru al containerului

În bibliotecă au apărut funcții, așa-numitele ghiduri de deducere , permițându-vă să faceți acest lucru:

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

Funcții noi pentru inserarea într-un tablou asociativ cu o cheie nerepetată

Pentru std::mapși std::unordered_mapau fost adăugate două funcții noi [52] .

#include <iostream> #include <hartă> clasă pereche { public : int valoare1 , valoare2 ; Pereche () : valoare1 ( 0 ), valoare2 ( 0 ) {} Pereche explicită ( int aValoare1 ) : valoare1 ( aValoare1 ), valoare2 ( 0 ) {} Pereche ( int aValoare1 , int aValoare2 ) : valoare1 ( aValoare1 ), valoare2 ( aValoare2 ) {} }; int main () { std :: map < std :: string , Pair > m ; // C++11 m [ "a" ] = Pereche ( 3 , 4 ); m . emplace ( "a" , 1 ); // Perechea este întotdeauna creată // C++17 m . insert_or_assign ( "a" , Pair ( 3 , 4 )); m . try_emplace ( "a" , 1 ); // Perechea este creată atunci când este necesar returnează 0 ; }

Noi funcții matematice

În spațiul de nume standard au fost introduse funcții matematice non-standard: beta, , , , , , , , , , , [53] [54] . Nu există niciunul în afara std (în ). cyl_bessel_i/j/kcyl_neumann[comp_]ellint_1/2/3expinthermite[assoc_]laguerre[assoc_]legendreriemann_zetasph_besselsph_legendresph_neumannmath.h

Din prima propoziție (2010): „Sperăm că adoptarea acestei propuneri va transmite un mesaj către diferitele comunități de calcul că, în ciuda credinței populare, C++ este, de asemenea, destul de potrivit pentru industria lor”. Atunci nu a fost acceptat. Acum, principalii furnizori de biblioteci ( Dinkumware , Boost , GCC ) au deja aceste caracteristici.

De asemenea, a adăugat calculul GCD [55] și LCM [56] , funcția de reducere la interval ( ) [57] , ipotenuza tridimensională . clamphypot(x, y, z)

Biblioteca sistemului de fișiere

O bibliotecă de sistem de fișiere bazată pe boost::filesystemvă permite: [58]

  • internaționalizarea automată a numelor de fișiere în funcție de caracteristicile sistemului de operare. Biblioteca ascunde codarea în care funcționează și ea însăși convertește numele în cea dorită - cel puțin la un octet definit de local și diverse variante Unicode;
  • parcurgerea directoarelor (inclusiv recursive);
  • definirea tipurilor de fișiere (obișnuit, director , socket ...);
  • împărțirea căii către fișier în componente: unitate, director, nume și extensie;
  • crearea de directoare, copierea fișierelor, ștergerea directoarelor și fișierelor (inclusiv recursive);
  • obținerea de nume pentru fișierele temporare .

Tipuri de variabile

Exista o clasă capabilă să conţină date de orice tip [59] [60] . Sunt necesare implementări pentru a se potrivi obiectelor mici fără a aloca memorie. Funcția necesită o potrivire exactă a tipului și nu va oferi nimic dacă este în interiorul . std::anyanyany_castany_cast<double>int

std :: cout << std :: boolalpha ; std :: orice a = 1 ; std :: cout << a . tip (). nume () << ": " << std :: any_cast < int > ( a ) << std :: endl ; a = 3,14 ; std :: cout << a . tip (). nume () << ": " << std :: any_cast < double > ( a ) << std :: endl ; a = adevărat ; std :: cout << a . tip (). nume () << ": " << std :: any_cast < bool > ( a ) << std :: endl ; // i: 1 // d: 3,14 // b: adevărat

Există, de asemenea, mai simple std::variant<int, bool, double>și std::optional<T>.

Funcții de conversie număr-în text de nivel scăzut

Un dezavantaj cunoscut al C++: pentru conversia la nivel scăzut a numerelor în text fără alocare de memorie, trebuie să rulați unul greu și nesigur sprintf, iar conversia încorporată a textului într-un număr rămas cu C este destul de nesigură.

Acum sunt încorporate superviteze independente de local from_chars[61] și to_chars[62] . Sunt proiectate în așa fel încât să nu necesite (și să nu producă) un zero de închidere și să poată funcționa, de exemplu, pe string_view. Datorită limitărilor și independenței locale, acestea sunt destinate în primul rând pentru JSON și XML , unde este nevoie de o viteză extraordinară.

Tip nou polymorphic_allocator

Structurile de date STL ( șiruri de caractere , vectori etc.) conțin un parametru șablon - un alocator de memorie. Acest alocător funcționează ca un concept de programare generic , nu ca o interfață orientată pe obiecte: alocarea memoriei pe heap și pool are ca rezultat diferite tipuri incompatibile. O clasă  este un început standard pentru o sarcină rară: în funcție de anumite condiții, alocați memorie fie în heap, fie în pool. polymorphic_allocator

În sine , nu  este o interfață, dar este asociată cu o interfață . polymorphic_allocatormemory_resource

Șablon nou std::invoke

Permite apelarea consecventă a funcțiilor, obiectelor cu operatorul () ( functors ) și obiectelor lambda [63] . De asemenea, au adăugat funcții , , . is_invocableis_invocable_rinvoke_result

Versiuni paralele ale algoritmilor STL

Pentru 69 de algoritmi din , și versiuni paralele au fost inventate [64] [65] [66] . <algorithm><numeric><memory>

Vezi și

Link -uri

  • Proiect de standard, N4659 , din 21.03.2017

Note

  1. ISO/IEC 14882:2017 . Preluat la 4 decembrie 2017. Arhivat din original la 17 mai 2013.
  2. Etape recente: C++17 aproape complet complet, a doua rundă de TS-uri acum în curs de dezvoltare . Preluat la 28 martie 2016. Arhivat din original la 8 septembrie 2020.
  3. N3981: Eliminarea trigrafelor??! (Richard Smith) (6 mai 2014). Preluat la 28 martie 2016. Arhivat din original la 9 iulie 2018.
  4. Comentariu IBM privind pregătirea pentru un viitor advers Trigraph în C++17 Arhivat 11 septembrie 2018 la Wayback Machine , document IBM N4210, 2014-10-10.
  5. Eliminați utilizarea învechită a cuvântului cheie de registru . Preluat la 20 august 2018. Arhivat din original la 14 septembrie 2017.
  6. Eliminați operatorul depreciat++(bool) . Preluat la 20 august 2018. Arhivat din original la 11 septembrie 2017.
  7. Eliminarea specificațiilor de excepție depreciate din C++17 . Preluat la 20 august 2018. Arhivat din original la 13 septembrie 2017.
  8. N4190: Înlăturarea auto_ptr, random_shuffle() și a lucrurilor <funcționale> vechi (Stephan T. Lavavej) . Preluat la 28 martie 2016. Arhivat din original la 20 octombrie 2017.
  9. 1 2 3 Actualizări ale raportului meu de călătorie . Data accesului: 28 martie 2016. Arhivat din original pe 19 martie 2015.
  10. Eliminați aliasurile iostreams depreciate . Preluat la 20 august 2018. Arhivat din original la 22 august 2017.
  11. Eliminarea suportului alocătorului în funcția std:: (rev 1) . Preluat la 20 august 2018. Arhivat din original la 17 septembrie 2017.
  12. Deprecierea părților de bibliotecă vestigială în C++17 . Preluat la 20 august 2018. Arhivat din original la 13 septembrie 2017.
  13. Deprecierea <codecvt> . Preluat la 20 august 2018. Arhivat din original la 16 septembrie 2017.
  14. Rezoluție propusă pentru CA 14 (shared_ptr use_count/unique) . Preluat la 20 august 2018. Arhivat din original la 7 iulie 2017.
  15. Rezolvarea GB 55, US 84, US 85, US 86 . Preluat la 20 august 2018. Arhivat din original la 5 iulie 2017.
  16. N4259: Formulare pentru std::uncaught_exceptions (Herb Sutter) . Preluat la 28 martie 2016. Arhivat din original la 29 noiembrie 2014.
  17. 1 2 3 4 5 Noi lucrări în limbajul de bază adoptate pentru C++17 . Preluat la 28 martie 2016. Arhivat din original la 27 aprilie 2015.
  18. Sursa . Preluat la 31 mai 2022. Arhivat din original la 16 noiembrie 2017.
  19. C++17 ar trebui să se refere la C11 în loc de C99 . Preluat la 20 august 2018. Arhivat din original la 13 septembrie 2017.
  20. N3922: Reguli noi pentru deducerea automată din lista de inițializare înlănțuită (James Dennett) . Preluat la 28 martie 2016. Arhivat din original la 10 august 2015.
  21. Faceți ca specificațiile de excepție să facă parte din sistemul de tip . Preluat la 20 august 2018. Arhivat din original la 12 septembrie 2017.
  22. Alocarea dinamică a memoriei pentru datele supra-aliniate . Preluat la 20 august 2018. Arhivat din original la 8 septembrie 2017.
  23. [ http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0145r3.pdf Rafinarea Ordinului de evaluare a expresiei pentru Idiomatic C++] . Preluat la 23 august 2018. Arhivat din original la 26 august 2018.
  24. N4268: Permite evaluarea constantă pentru toate argumentele șablon care nu sunt de tip (Richard Smith) . Preluat la 28 martie 2016. Arhivat din original la 12 martie 2016.
  25. Generalizarea buclei For bazate pe interval . Preluat la 23 august 2018. Arhivat din original la 5 octombrie 2017.
  26. 1 2 Noi lucrări standard de bibliotecă adoptate pentru C++17 . Preluat la 28 martie 2016. Arhivat din original la 29 noiembrie 2014.
  27. N4284: Iteratori contigui (Jens Maurer) . Preluat la 28 martie 2016. Arhivat din original la 29 noiembrie 2014.
  28. N4267: Adăugarea de caractere literale u8 (Richard Smith) . Preluat la 28 martie 2016. Arhivat din original la 28 octombrie 2015.
  29. Descurajați temporar memory_order_consume . Preluat la 20 august 2018. Arhivat din original la 16 ianuarie 2018.
  30. Scopul memory_order_consume în C++11 . Preluat la 15 august 2019. Arhivat din original la 11 noiembrie 2019.
  31. N3928: Extinderea static_assert, v2 (Walter E. Brown) . Preluat la 28 martie 2016. Arhivat din original la 11 august 2015.
  32. Astfel, autorii PVS-Studio s- au plâns adesea de o eroare: programatorul a clear()scris empty().
  33. N4051: Permite nume de tip într-un parametru șablon șablon (Richard Smith) . Preluat la 28 martie 2016. Arhivat din original la 11 august 2015.
  34. Declarație obligatorie structurată (începând cu C++17) Arhivată 8 septembrie 2020 la Wayback Machine en.cppreference.com
  35. N4230: Definiția spațiului de nume imbricat (Robert Kawulak, Andrew Tomazos) . Preluat la 28 martie 2016. Arhivat din original la 3 august 2015.
  36. N4266: Atribute pentru spații de nume și enumeratori (Richard Smith) . Data accesului: 28 martie 2016. Arhivat din original pe 6 martie 2016.
  37. constexpr dacă: O sintaxă ușor diferită . Preluat la 20 august 2018. Arhivat din original la 7 octombrie 2017.
  38. N4295: Folding expressions (Andrew Sutton, Richard Smith) . Preluat la 28 martie 2016. Arhivat din original la 4 aprilie 2015.
  39. Literale flotante hexazecimale pentru C++ . Preluat la 12 iunie 2019. Arhivat din original la 22 august 2017.
  40. Declarații de selecție cu inițializator . Consultat la 12 iunie 2019. Arhivat din original la 6 octombrie 2017.
  41. Declararea parametrilor șablonului non-tip cu auto . Preluat la 7 august 2020. Arhivat din original la 16 septembrie 2017.
  42. Captură Lambda a *this by Value ca [=,*this ] . Preluat la 7 august 2020. Arhivat din original la 22 august 2017.
  43. Reguli de construcție pentru valorile clasei enumerate . Preluat la 7 august 2020. Arhivat din original la 9 decembrie 2017.
  44. C++17 ar trebui să se refere la C11 în loc de C99 . Consultat la 18 decembrie 2016. Arhivat din original la 13 noiembrie 2016.
  45. N4280: Dimensiunea non-membru() și altele (Riccardo Marcangelo) . Data accesului: 28 martie 2016. Arhivat din original pe 9 martie 2015.
  46. Formularea pentru bool_constant, revizuirea 1 . Preluat la 1 ianuarie 2020. Arhivat din original la 14 octombrie 2017.
  47. Copie arhivată . Preluat la 1 ianuarie 2020. Arhivat din original la 28 august 2017.
  48. Copie arhivată . Preluat la 1 ianuarie 2020. Arhivat din original la 10 octombrie 2017.
  49. Copie arhivată . Preluat la 1 ianuarie 2020. Arhivat din original la 5 iulie 2017.
  50. P0154R1 constexpr std::hardware_{constructive,distructive}_interference_size .
  51. std::shared_mutex - cppreference.com . Preluat la 30 august 2019. Arhivat din original la 30 august 2019.
  52. Interfață de inserare îmbunătățită pentru std::{unordered_,}map (revizuită) . Preluat la 28 martie 2016. Arhivat din original la 27 aprilie 2015.
  53. Copie arhivată . Preluat la 20 august 2019. Arhivat din original la 17 septembrie 2019.
  54. Funcții speciale matematice pentru C++17, v5 . Preluat la 28 martie 2016. Arhivat din original la 5 aprilie 2016.
  55. std::gcd - cppreference.com . Preluat la 30 august 2019. Arhivat din original la 28 martie 2019.
  56. std::lcm - cppreference.com . Preluat la 30 august 2019. Arhivat din original la 28 martie 2019.
  57. std::clamp - cppreference.com . Preluat la 30 august 2019. Arhivat din original la 30 august 2019.
  58. Propunerea bibliotecii sistemului de fișiere (Beman Dawes) . Preluat la 28 martie 2016. Arhivat din original la 20 iulie 2016.
  59. C++ Extensions for Library Fundamentals, Versiunea 2, Working Draft . Preluat la 30 august 2019. Arhivat din original la 25 august 2019.
  60. std::any - cppreference.com . Preluat la 30 august 2019. Arhivat din original la 30 august 2019.
  61. std::from_chars - cppreference.com . Preluat la 30 august 2019. Arhivat din original la 30 august 2019.
  62. std::to_chars - cppreference.com . Preluat la 30 august 2019. Arhivat din original la 30 august 2019.
  63. O propunere de adăugare a șablonului funcției de invocare (Reviziunea 1) . Preluat la 1 ianuarie 2020. Arhivat din original la 6 octombrie 2017.
  64. Extensii pentru paralelism - cppreference.com . Preluat la 5 februarie 2021. Arhivat din original la 12 noiembrie 2020.
  65. Paralelismul TS ar trebui să fie standardizat . Preluat la 28 martie 2016. Arhivat din original la 5 aprilie 2016.
  66. Utilizarea algoritmilor paraleli C++17 pentru o performanță mai bună | Blogul echipei C++ . Preluat la 5 februarie 2021. Arhivat din original la 24 ianuarie 2021.