C++ 17 funktioner

C++ 17 funktioner

I år får vi en ny version af C++:C++17!
I denne mega lange artikel har jeg lavet en liste over alle funktioner af den nye standard.

Tag et kig og se, hvad vi får!

  • Introduktion
  • Sprogfunktioner
    • Nye automatiske regler for direkte-liste-initialisering
    • static_assert uden besked
    • typenavn i en skabelonskabelonparameter
    • Fjernelse af trigrafer
    • Definition af indlejret navneområde
    • Attributter for navnerum og tællere
    • u8 bogstaver
    • Tillad konstant evaluering for alle ikke-type skabelonargumenter
    • Foldningsudtryk
    • Unære foldudtryk og tomme parameterpakker
    • Fjern forældet brug af registerKeyword
    • Fjern Deprecatedoperator++(bool)
    • Fjernelse af forældede undtagelsesspecifikationer fra C++17
    • Gør undtagelsesspecifikationer til en del af typesystemet
    • Aggregeret initialisering af klasser med basisklasser
    • Lambda-optagelse af *dette
    • Brug af attributnavneområder uden gentagelse
    • Dynamisk hukommelsesallokering til overjusterede data
    • __has_include in preprocessorconditionals
    • Skabelonargumentfradrag for klasseskabeloner
    • Ikke-type skabelonparametre med autotype
    • Garanteret kopielision
    • Ny specifikation for nedarvede konstruktører (DR1941 et al.)
    • Direkte-liste-initialisering af opregninger
    • Strengere udtryksevalueringsrækkefølge
    • constexpr lambda-udtryk
    • Forskellige start- og sluttyper i interval-basedfor
    • [[fallthrough]] attribut
    • [[nodiscard]] attribut
    • [[maybe_unused]] attribut
    • Ignorer ukendte attributter
    • Pakkeudvidelser ved hjælp af erklæringer
    • Strukturerede bindende erklæringer
    • Hexadecimale bogstaver med flydende komma
    • init-sætninger for if andswitch
    • Inline variabler
    • DR:Matchning af skabelonskabelon-argumenter udelukker kompatible skabeloner
    • std::uncaught_exceptions()
    • constexpr if-sætninger
      • SFINAE
      • Tag-afsendelse
      • if constexpr
  • Bibliotekets funktioner
    • Flettet:The Library Fundamentals 1 TS (de fleste dele)
    • Fjernelse af nogle forældede typer og funktioner, herunderstd::auto_ptr, std::random_shuffle og gamle funktionsadaptere
    • Merged:The Parallelism TS, a.k.a. "ParallelSTL.",
    • Flettet:Filsystem TS,
    • Flettet:The Mathematical Special FunctionsIS,
    • Forbedring af std::pair andstd::tuple
    • std::shared_mutex (utidsindstillet)
    • Variant
    • Splejsning af kort og sæt
  • Bidragydere
  • Oversigt

Introduktion

Opdateret :Dette indlæg blev opdateret den 15. marts 2018.

Listen er for det meste færdig! Stadig nogle beskrivelser kunne forbedres eller flere eksempler kunne gives.

Hvis du har kodeeksempler, bedre forklaringer eller ideer, så lad mig vide det! Jeg er glad for at opdatere det nuværende indlæg, så det har en vis reel værdi for andre.

Planen er at have en liste over funktioner med nogle grundlæggende forklaringer, et lille eksempel (hvis muligt) og nogle ekstra ressourcer, plus en note om tilgængelighed i compilere. Sandsynligvis kan de fleste funktioner kræve separate artikler eller endda hele kapitler i bøger, så listen her vil kun være en hurtig start.

Se dette github repo:github/fenbf/cpp17features.Tilføj en pull-anmodning for at opdatere indholdet.

Listen kommer fra følgende ressourcer:

  • SÅ:Hvad er de nye funktioner i C++17?
  • cppreference.com/C++ compilersupport.
  • AnthonyCalandra/modern-cpp-features cheatsheet - det inkluderer desværre ikke alle funktionerne i C++17.
  • plus andre resultater og omtaler

Og en af ​​de vigtigste ressourcer:N4659, 2017-03-21, Draft,Standard for Programming LanguageC++

  • fra isocpp.org.

Derudover er der en officiel liste over ændringer:P0636r0:Ændringer mellem C++14 og C++17 DIS

Du kan også få fat i min liste over kortfattede beskrivelser af alle C++17 - Det er et referencekort på én side:

Download en gratis kopi af mit C++17 CheatSheet!

Jeg arbejder også på en lidt detaljeret serie:

  1. Retninger og udfasning
  2. Sprogafklaring
  3. Skabeloner
  4. Attributter
  5. Forenkling
  6. Ændringer i biblioteket - Filsystem
  7. Bibliotekændringer - ParallelSTL
  8. Bibliotek ændringer -Utils
  9. Afslut, bonus - med en gratis e-bog! :)

Ressourcer om C++17 STL:

  • C++17 i detaljer af Bartek!

Sprogfunktioner

Nye automatiske regler for direct-list-initialization

N3922

Retter nogle sager med autotypefradrag. Den fulde baggrund kan findes i Auto og braced-init-lister af Ville Voutilainen.

Det løser problemet med at udlede std::initializer_list som:

auto x = foo(); // copy-initialization
auto x{foo}; // direct-initialization, initializes an initializer_list
int x = foo(); // copy-initialization
int x{foo}; // direct-initialization

Og for den direkte initialisering er nye regler:

  • For en afstivet-init-liste med kun et enkelt element, vil automatisk fradrag udledes af denne post;
  • For en indgangsliste med mere end ét element vil automatisk fradrag være dårligt udformet.

Grundlæggende auto x { 1 }; vil nu blive udledt som int , men før var det en initialiseringsliste.

static_assert uden besked

N3928

Selvforklarende. Det tillader bare at have tilstanden uden at sende beskeden, version med beskeden vil også være tilgængelig. Det vil være kompatibelt med andre påstande som BOOST_STATIC_ASSERT (det tog ikke nogen besked fra starten).

typenavn i en skabelonskabelonparameter

N4051

Giver dig mulighed for at bruge typename i stedet for class når du erklærer atemplate-skabelonparameter. Normal type parametre kan bruge dem i flæng, men skabelonskabelonparametre var begrænset tilclass , så denne ændring forener disse former noget.

template <template <typename...> typename Container>
//            used to be invalid ^^^^^^^^
struct foo;

foo<std::vector> my_foo;

Fjernelse af trigrafer

N4086

Fjerner ??= , ??( , ??> , …

Gør implementeringen en smule enklere, se MSDNTrigraphs

Definition af indlejret navneområde

N4230

Giver mulighed for at skrive:

namespace A::B::C {
   //…
}

I stedet for:

namespace A {
    namespace B {
        namespace C {
            //…
        }
    }
}

Attributter for navnerum og tællere

N4266

Tillader attributter på tællere og navnerum. Flere detaljer iN4196.

enum E {
  foobar = 0,
  foobat [[deprecated]] = foobar
};

E e = foobat; // Emits warning

namespace [[deprecated]] old_stuff{
    void legacy();
}

old_stuff::legacy(); // Emits warning

u8 bogstaver

N4267

Compileren vil rapportere fejl, hvis tegn ikke kan passe ind i u8 ASCII-område.

Reference:

  • cppreference.com/characterliteral
  • SÅ:Hvad er meningen med UTF-8-tegn-literalerne foreslået for C++17?

Tillad konstant evaluering for alle ikke-type skabelonargumenter

N4268

Fjern syntaktiske begrænsninger for pointere, referencer og pointere til medlemmer, der vises som ikke-type skabelonparametre:

For eksempel:

template<int *p> struct A {};
int n;
A<&n> a; // ok

constexpr int *p() { return &n; }
A<p()> b; // error before C++17

Foldningsudtryk

N4295

Mere baggrund her i P0036

Tillader at skrive kompakt kode med variadiske skabeloner uden at bruge eksplicit rekursion.

Eksempel:

template<typename... Args>
auto SumWithOne(Args... args){
    return (1 + ... + args);
}

Artikler:

  • Barteks kodningsblog:C++17 i detaljer:Skabeloner
  • C++-sandheder:Folding Monadic Functions
  • Simon Brand:Eksploderende tupler med foldeudtryk
  • Baptiste Wicht:C++17 FoldExpressions
  • Foldningsudtryk -ModernesCpp.com

Unære foldudtryk og tomme parameterpakker

P0036R0

Hvis parameterpakken er tom, er værdien af ​​foldningen:

For enhver operator, der ikke er angivet ovenfor, er et unært foldudtryk med en tom parameterpakke dårligt udformet.

Fjern forældet brug af registerets søgeord

P0001R1

register søgeord blev forældet i 2011 C++-standarden. C++17 forsøger at rydde standarden, så nøgleordet er nu fjernet. Dette søgeord er reserveret nu og kan blive genbrugt i fremtidige revisioner.

Fjern forældet operator++(bool)

P0002R1

++ operatoren for bool blev forældet i den oprindelige C++-standard fra 1998, og det er på tide at fjerne det formelt.

Fjernelse af forældede undtagelsesspecifikationer fra C++17

P0003R5

Dynamiske undtagelsesspecifikationer blev forældet i C++11. Dette papir foreslår formelt at fjerne funktionen fra C++17, mens den (stadig) forældede throw() bibeholdes specifikation udelukkende som et alias for noexcept(true) .

Gør undtagelsesspecifikationer til en del af typesystemet

P0012R1

Tidligere undtagelsesspecifikationer for en funktion hørte ikke til funktionens type, men den vil være en del af den.

Vi får en fejl i sagen:

void (*p)();
void (**pp)() noexcept = &p;   // error: cannot convert to pointer to noexcept function

struct S { typedef void (*p)(); operator p(); };
void (*q)() noexcept = S();   // error: cannot convert to pointer to noexcept function

Aggregeret initialisering af klasser med basisklasser

P0017R1

Hvis en klasse var afledt af en anden type, kunne du ikke bruge aggregatinitialisering. Men nu er begrænsningen fjernet.

struct base { int a1, a2; };
struct derived : base { int b1; };

derived d1{{1, 2}, 3};      // full explicit initialization
derived d1{{}, 1};          // the base is value initialized

For at opsummere:fra standarden:

Lambda-optagelse af *dette

P0018R3

this pointer er implicit fanget af lambdas inde i medlemsfunktioner (hvis du bruger en standard capture, såsom [&] eller [=] ). Medlemsvariabler er altid tilgået af denne markør.

Eksempel:

struct S {
   int x ;
   void f() {
      // The following lambda captures are currently identical
      auto a = [&]() { x = 42 ; } // OK: transformed to (*this).x
      auto b = [=]() { x = 43 ; } // OK: transformed to (*this).x
      a();
      assert( x == 42 );
      b();
      assert( x == 43 );
   }
};

Nu kan du bruge *this når du erklærer en lambda, for eksempelauto b = [=, *this]() { x = 43 ; } . På den måde this er fanget af værdi. Bemærk, at formen [&,dette] er overflødig, men accepteret for kompatibilitet med ISO C++14.

Indfangning efter værdi kan være særlig vigtig for asynkron påkaldelse, parallel behandling.

Brug af attributnavneområder uden gentagelse

P0028R4

Et andet navn for denne funktion var "Brug af ikke-standardegenskaber" i P0028R3 og PDF:P0028R2(rationale, eksempler).

Forenkler det tilfælde, hvor du vil bruge flere attributter, såsom:

void f() {
    [[rpr::kernel, rpr::target(cpu,gpu)]] // repetition
    do-task();
}

Foreslået ændring:

void f() {
    [[using rpr: kernel, target(cpu,gpu)]]
    do-task();
}

Denne forenkling kan måske hjælpe, når du bygger værktøjer, der automatisk oversætter kommenteret sådan kode til en anden programmeringsmodell.

Dynamisk hukommelsesallokering til overjusterede data

P0035R4

I følgende eksempel:

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

C++11/14 specificerede ikke nogen mekanisme, hvorved overjusterede data dynamisk kan allokeres korrekt (dvs. respekt for justeringen af ​​dataene). I eksemplet ovenfor er en implementering af C++ ikke kun nødvendig for at allokere korrekt justeret hukommelse til arrayet, af praktiske formål er det næsten nødvendigt at udføre allokeringen forkert.

C++17 retter dette hul ved at introducere yderligere hukommelsesallokeringsfunktioner, der bruger align parameter:

void* operator new(std::size_t, std::align_val_t);
void* operator new[](std::size_t, std::align_val_t);
void operator delete(void*, std::align_val_t);
void operator delete[](void*, std::align_val_t);
void operator delete(void*, std::size_t, std::align_val_t);
void operator delete[](void*, std::size_t, std::align_val_t);

__has_include in preprocessor conditionals

P0061R1

Denne funktion gør det muligt for et C++-program direkte, pålideligt og bærbart at bestemme, om en biblioteksheader er tilgængelig til medtagelse eller ej.

Eksempel:Dette viser en måde at bruge en valgfri biblioteksfacilitet kun, hvis den er tilgængelig.

#if __has_include(<optional>)
#  include <optional>
#  define have_optional 1
#elif __has_include(<experimental/optional>)
#  include <experimental/optional>
#  define have_optional 1
#  define experimental_optional 1
#else
#  define have_optional 0
#endif

Skabelonargumentfradrag for klasseskabeloner

P0091R3

Før C++17 fungerede skabelonfradrag for funktioner, men ikke for klasser.
For eksempel var følgende kode lovlig:

void f(std::pair<int, char>);

f(std::make_pair(42, 'z'));

fordi std::make_pair er en skabelonfunktion (så vi kan udføre pladefradrag).
Men følgende var ikke:

void f(std::pair<int, char>);

f(std::pair(42, 'z'));

Selvom det er semantisk ækvivalent. Dette var ikke lovligt, fordistd::pair er en skabelonklasse , og skabelonklasser kunne ikke anvende type-fradrag i deres initialisering.

Så før C++17 skal man skrive typerne eksplicit ud, selv tænkte det ikke tilføjer nogen ny information:

void f(std::pair<int, char>);

f(std::pair<int, char>(42, 'z'));

Dette er rettet i C++17, hvor skabelonklassekonstruktører kan udlede typeparametre. Syntaksen til at konstruere sådanne skabelonklasser er derfor i overensstemmelse med syntaksen til at konstruere ikke-skabelonklasser.

todo:fradragsvejledninger.

  • Barteks kodningsblog:C++17 i detaljer:Skabeloner
  • En 4-minutters episode af C++ Weekly på klasseskabelonargumenttypededuktion
  • Et afsnit på 4 minutter af C++ Weekly på deductionguides
  • Moderne C++ funktioner - Klasseskabelon ArgumentDeduction -

Ikke-type skabelonparametre med autotype

P0127R2

Udled automatisk type på ikke-type skabelonparametre.

template <auto value> void f() { }
f<10>();               // deduces int

Rejserapport:Sommer ISO C++ standarder opfylder (Oulu) | Sutter'sMill

Garanteret kopi-elision

P0135R1

Kopi-elision for midlertidige objekter, ikke for navngivet RVO.

Artikler:

  • Barteks kodningsblog:C++17 i detaljer:sprogforklaringer
  • Jonas Devlieghere:Guaranteed CopyElision

Ny specifikation for nedarvede konstruktører (DR1941 et al)

P0136R1

Mere beskrivelse og begrundelse i P0136R0. Nogle uddrag nedenfor:

En arvende konstruktør fungerer ikke som enhver anden form for brugserklæring. Alle andre bruger-deklarationer gør nogle sæt af erklæringer synlige for navneopslag i en anden sammenhæng, men en nedarvning af constructor-erklæringer erklærer en ny constructor, der blot uddelegerer til originalen.

Denne funktion ændrer nedarvning af konstruktørerklæring fra at erklære aktiv for nye konstruktører til at gøre et sæt af basisklassekonstruktører synlige i en afledt klasse, som om de var afledte klassekonstruktører. (Når en sådan konstruktør bruges, vil de yderligere afledte klasseunderobjekter også blive konstrueret implicit. som af en defaulteddefault-konstruktør). Sagt på en anden måde:få nedarvning af en konstruktør til at fungere ligesom at arve et hvilket som helst andet basisklassemedlem, i det omfang det er muligt.

Denne ændring påvirker betydningen og gyldigheden af ​​nogle programmer, men disse ændringer forbedrer konsistensen og forståeligheden af ​​C++.

// Hiding works the same as for other member
// using-declarations in the presence of default arguments
struct A {
  A(int a, int b = 0);
  void f(int a, int b = 0);
};
struct B : A {
  B(int a);      using A::A;
  void f(int a); using A::f;
};
struct C : A {
  C(int a, int b = 0);      using A::A;
  void f(int a, int b = 0); using A::f;
};

B b(0); // was ok, now ambiguous
b.f(0); // ambiguous (unchanged)

C c(0); // was ambiguous, now ok
c.f(0); // ok (unchanged)

// Inheriting constructor parameters are no longer copied
struct A { A(const A&) = delete; A(int); };
struct B { B(A); void f(A); };
struct C : B { using B::B; using B::f; };
C c({0}); // was ill-formed, now ok (no copy made)
c.f({0}); // ok (unchanged)

Direkte-liste-initialisering af opregninger

P0138R2

Giver mulighed for at initialisere enum-klasse med en fast underliggende type:

enum class Handle : uint32_t { Invalid = 0 };
Handle h { 42 }; // OK

Giver mulighed for at skabe "stærke typer", der er nemme at bruge...

Strengere udtryksevalueringsrækkefølge

P0145R3

I en nøddeskal givet et udtryk såsom f(a, b, c) , rækkefølgen, hvori underudtrykkene f, a, b, c (som har vilkårlige former) evalueres, efterlades uspecificeret af standarden.

// unspecified behaviour below!
f(i++, i);

v[i] = i++;

std::map<int, int> m;
m[0] = m.size(); // {{0, 0}} or {{0, 1}} ?

Oversigt over ændringer:

  • Postfix-udtryk evalueres fra venstre mod højre. Dette inkluderer funktionskald og medlemsvalgsudtryk.
  • Tildelingsudtryk evalueres fra højre mod venstre. Dette inkluderer sammensatte opgaver.
  • Operander til skiftoperatorer evalueres fra venstre mod højre.

Reference:

  • Barteks kodningsblog:C++17 i detaljer:sprogforklaringer
  • C++ Evalueringsrækkefølge,cppreference
  • SÅ:Hvad er garantierne for evalueringsordre introduceret af C++17?
  • Hvordan kompakt kode kan blive buggy-kode:at blive fanget af rækkefølgen af ​​evalueringer, FluentC++

constexpr lambda-udtryk

P0170R1

consexpr kan bruges i sammenhæng med lambdas.

constexpr auto ID = [] (int n)  { return n; };
constexpr int I = ID(3);
static_assert(I == 3);

constexpr int AddEleven(int n) {
  // Initialization of the 'data member' for n can
  // occur within a constant expression since 'n' is
  // of literal type.
  return [n] { return n + 11; }();
}
static_assert(AddEleven(5) == 16);

Artikler

  • Et afsnit på 5 minutter af Jason Turners C++ Weekly om constexprlambdas
  • Lambda-ekspressionssammenligning mellem C++11, C++14 og C++17

Forskellige start- og sluttyper i intervalbaseret for

P0184R0

Ændring af definitionen af ​​område baseret på fra:

{
   auto && __range = for-range-initializer;
   for ( auto __begin = begin-expr,
              __end = end-expr;
              __begin != __end;
              ++__begin ) {
        for-range-declaration = *__begin;
        statement
   }
}

Ind i:

{
  auto && __range = for-range-initializer;
  auto __begin = begin-expr;
  auto __end = end-expr;
  for ( ; __begin != __end; ++__begin ) {
    for-range-declaration = *__begin;
    statement
  }
}

Typer af __begin og __end kan være anderledes; kun sammenligningsoperatøren er påkrævet. Denne lille ændring giver Range TS-brugere en bedre oplevelse.

[[fallthrough]] attribut

P0188R1

Angiver, at et fald i en switch-erklæring er bevidst, og at der ikke bør udsendes en advarsel for det. Flere detaljer i P0068R0.

switch (c) {
case 'a':
    f(); // Warning emitted, fallthrough is perhaps a programmer error
case 'b':
    g();
[[fallthrough]]; // Warning suppressed, fallthrough is intentional
case 'c':
    h();
}

[[nodiscard]] attribut

P0189R1

[[nodiscard]] bruges til at understrege, at returværdien af ​​en funktion ikke skal kasseres, på grund af en compiler-advarsel. Flere detaljer i P0068R0.

[[nodiscard]] int foo();
void bar() {
    foo(); // Warning emitted, return value of a nodiscard function is discarded
}

Denne attribut kan også anvendes på typer for at markere alle funktioner, der returnerer denne type som [[nodiscard]] :

[[nodiscard]] struct DoNotThrowMeAway{};
DoNotThrowMeAway i_promise();
void oops() {
    i_promise(); // Warning emitted, return value of a nodiscard function is discarded
}

Artikler:

  • Barteks kodningsblog:Håndhævelse af kodekontrakter med[[nodiscard]]
  • En 4 min video om nodiscard i Jason Turners C++ Weekly

[[maybe_unused]] attribut

P0212R1

Undertrykker kompileringsadvarsler om ubrugte enheder, når de er deklareret med [[maybe_unused]] . Flere detaljer i P0068R0.

                 static void impl1() { ... } // Compilers may warn about this
[[maybe_unused]] static void impl2() { ... } // Warning suppressed


void foo() {
                      int x = 42; // Compilers may warn about this
     [[maybe_unused]] int y = 42; // Warning suppressed
}

En 3 min video om maybe_unused i Jason Turners C++ Weekly

Ignorer ukendte attributter

P0283R2

Præciserer, at implementeringer skal ignorere alle attributnavneområder, som de ikke understøtter, da dette plejede at være uspecificeret. Flere detaljer i P0283R1.

//compilers which don't support MyCompilerSpecificNamespace will ignore this attribute
[[MyCompilerSpecificNamespace::do_special_thing]]
void foo();

Pakkeudvidelser i use-declarations

P0195R2

Giver dig mulighed for at indsætte navne med brug af erklæringer fra alle typer i aparameterpakke.

For at afsløre operator() fra alle basisklasser i en variadictemplate, plejede vi at ty til rekursion:

template <typename T, typename... Ts>
struct Overloader : T, Overloader<Ts...> {
    using T::operator();
    using Overloader<Ts...>::operator();
    // […]
};

template <typename T> struct Overloader<T> : T {
    using T::operator();
};

Nu kan vi blot udvide parameterpakken i using-declaration :

template <typename... Ts>
struct Overloader : Ts... {
    using Ts::operator()...;
    // […]
};

Bemærkninger

  • Implementeret i GCC 7.0, se denne ændring.

Strukturerede bindende erklæringer

P0217R3
P0615R0:Omdøbning til strukturerede bindinger

Hjælper ved brug af tupler som returtype. Det vil automatisk oprette variabler og tie dem. Flere detaljer iP0144R0. Navnet "Decomposition Declaration" blev også brugt, men endelig accepterer standarden at bruge "Structured Binding Declarations" (afsnit 11.5)

For eksempel:

int a = 0;
double b = 0.0;
long c = 0;
std::tie(a, b, c) = tuple; // a, b, c need to be declared first

Nu kan vi skrive:

auto [ a, b, c ] = tuple;

Sådanne udtryk virker også på strukturer, par og arrays.

Artikler:

  • Steve Lorimer, C++17 StructuredBindings
  • jrb-programmering, emulering af C++17-strukturerede bindinger inC++14
  • Simon Brand, tilføjer understøttelse af C++17-dekomponeringserklæring til dine klasser

Hexadecimal floating-point-literals

P0245R1

Giver mulighed for at udtrykke nogle specielle flydende kommaværdier, f.eks. skrives den mindste normale IEEE-754 enkelt præcisionsværdi let som0x1.0p-126 .

init-sætninger for if og switch

P0305R1

Nye versioner af if- og switch-sætningerne til C++:if (init; condition) og switch (init; condition) .

Dette burde forenkle koden. For eksempel skulle du tidligere skrive:

{
    auto val = GetValue();
    if (condition(val))
        // on success
    else
        // on false...
}

Se, den val har et separat omfang, uden det vil det ‘lække’.

Nu kan du skrive:

if (auto val = GetValue(); condition(val))
    // on success
else
    // on false...

val er kun synlig inde i if og else udsagn, så det ikke 'lækker'.
condition kan være en hvilken som helst betingelse, ikke kun hvis val er sand/falsk.

Eksempler:

  • C++ Weekly - Ep 21 C++17's if og switch InitStatements

Inline variabler

P0386R2

Tidligere kunne kun metoder/funktioner angives som inline , nu kan du gøre det samme med variabler i en header-fil.

struct MyClass
{
    static const int sValue;
};

inline int const MyClass::sValue = 777;

Eller endda:

struct MyClass
{
    inline static const int sValue = 777;
};

Artikler

  • SÅ:Hvad er en inline-variabel, og hvad er den nyttig til?

DR:Matching af skabelonskabelon-argumenter udelukker kompatible skabeloner

P0522R0

Denne funktion løser kerneproblemet CWG150.

Fra avisen:

Eksempel:

template <template <int> class> void FI();
template <template <auto> class> void FA();
template <auto> struct SA { /* ... */ };
template <int> struct SI { /* ... */ };
FI<SA>();  // OK; error before this paper
FA<SI>();  // error

template <template <typename> class> void FD();
template <typename, typename = int> struct SD { /* ... */ };
FD<SD>();  // OK; error before this paper (CWG 150)

(Tilpasset fra kommentaren af ​​IncongruentModulo1)For et nyttigt eksempel, overvej noget som dette:

template <template <typename> typename Container>
struct A
{
    Container<int>    m_ints;
    Container<double> m_doubles;
};

I C++14 og tidligere, A<std::vector> ville ikke være gyldig (ignorerer typenavnet og ikke klassen før containeren) siden std::vector er erklæret som:

template <typename T, typename Allocator = std::allocator<T>> class vector;

Denne ændring løser dette problem. Før skulle du deklarere skabelon <template <typename...> typename Container> , som er mere tilladelig og flytter fejlen til en mindre eksplicit linje (nemlig erklæringen om m_ints hvor som helst struct A er implementeret /erklæret, i stedet for hvor strukturen er instantieret med den forkerte skabelontype.

std::uncaught_exceptions()

N4259

Mere baggrund i det originale papir:PDF:N4152 og GOTW udgave 47:UncaughtExceptions.

Funktionen returnerer antallet af ufangede undtagelsesobjekter i den aktuelle tråd.

Dette kan være nyttigt, når du implementerer korrekte Scope Guards, der også fungerer under afvikling af stakken.

Ovenstående citat stammer fra PDF:N4152.

constexpr hvis-udsagn

P0292R2

Det statiske-hvis for C++! Dette giver dig mulighed for at kassere grene af en ifstatement på kompileringstidspunktet baseret på en konstant udtryksbetingelse.

if constexpr(cond)
     statement1; // Discarded if cond is false
else
     statement2; // Discarded if cond is true

Dette fjerner meget af nødvendigheden af ​​tag-afsendelse og SFINAE:

SFINAE

template <typename T, std::enable_if_t<std::is_arithmetic<T>{}>* = nullptr>
auto get_value(T t) {/*...*/}

template <typename T, std::enable_if_t<!std::is_arithmetic<T>{}>* = nullptr>
auto get_value(T t) {/*...*/}

Tag-afsendelse

template <typename T>
auto get_value(T t, std::true_type) {/*...*/}

template <typename T>
auto get_value(T t, std::false_type) {/*...*/}

template <typename T>
auto get_value(T t) {
    return get_value(t, std::is_arithmetic<T>{});
}

if constexpr

template <typename T>
auto get_value(T t) {
     if constexpr (std::is_arithmetic_v<T>) {
         //...
     }
     else {
         //...
     }
}

Artikler:

  • Barteks kodningsblog:Forenkle kode med 'if constexpr' inC++17
  • LoopPerfect Blog, C++17 vs C++14 - Runde 1 -if-constexpr
  • SO:constexpr if andstatic_assert
  • Simon Brand:Simplificering af skabeloner og #ifdefs med ifconstexpr

Bibliotekets funktioner

For at få flere detaljer om biblioteksimplementering foreslår jeg disse links:

  • VS 2015 Update 2's STL er C++17 indtil videre FeatureComplete -Jan 2016
  • libstdc++, C++ 201zstatus
  • libc++ C++1z Status

Dette afsnit nævner kun nogle af de vigtigste dele af biblioteksændringer, det ville være for upraktisk at gå i detaljer om hver lille ændring.

Flettet:The Library Fundamentals 1 TS (de fleste dele)

P0220R1

Vi får følgende varer:

  • Tupler - Kald en funktion med en tuple af argumenter
  • Funktionelle objekter -Søgere
  • Valgfrie objekter
  • Elegant
  • streng_visning
  • Hukommelse:
    • Punkter om delt ejerskab
    • Klassehukommelsesressource
    • Klassehukommelsesressource
    • Adgang til programdækkende memory_resourceobjects
    • Pool ressourceklasser
    • Classmonotonic_buffer_resource
    • Aliaskabeloner ved hjælp af polymorfe hukommelsesressourcer
  • Algorithmer:
    • Søg
    • Sampling
  • shared_ptr håndterer native arrays:se fletning af shared_ptrchanges fra Library Fundamentals til C++17

Ordlyden fra disse komponenter kommer fra Library Fundamentals V2 for at sikre, at ordlyden inkluderer de seneste rettelser.

Ressourcer:

  • Marco Arena, string_view odi etamo
  • Barteks kodningsblog:C++17 i detaljer:Standard LibraryUtilities

Fjernelse af nogle forældede typer og funktioner, herunder std::auto_ptr, std::random_shuffle og gamle funktionsadaptere

N4190

  • Funktionsobjekter - unary_function/binary_function, ptr_fun(), andmem_fun()/mem_fun_ref()
  • Bindere - bind1st()/bind2nd()
  • auto_ptr
  • Random shuffle - random_shuffle(første, sidste) andrandom_shuffle(første, sidste, rng)

Merged:The Parallelism TS, a.k.a. "Parallel STL.",

P0024R2

Parallelle versioner/overbelastninger af de fleste standardalgoritmer. Plus et par nye algoritmer, såsom reducer, transform_reducer, for_each.

std::vector<int> v = genLargeVector();

// standard sequential sort
std::sort(v.begin(), v.end());

// explicitly sequential sort
std::sort(std::seq, v.begin(), v.end());

// permitting parallel execution
std::sort(std::par, v.begin(), v.end());

// permitting vectorization as well
std::sort(std::par_unseq, v.begin(), v.end());

Artikler:

  • Barteks kodningsblog:C++17 i detaljer:ParallelAlgorithms
  • Parallel algoritme for standardskabelonbiblioteket -ModernesCpp.com

Flettet:Filsystem TS,

P0218R1

namespace fs = std::filesystem;

fs::path pathToShow(/* ... */);
cout << "exists() = " << fs::exists(pathToShow) << "\n"
     << "root_name() = " << pathToShow.root_name() << "\n"
     << "root_path() = " << pathToShow.root_path() << "\n"
     << "relative_path() = " << pathToShow.relative_path() << "\n"
     << "parent_path() = " << pathToShow.parent_path() << "\n"
     << "filename() = " << pathToShow.filename() << "\n"
     << "stem() = " << pathToShow.stem() << "\n"
     << "extension() = " << pathToShow.extension() << "\n";

Artikler:

  • Barteks kodningsblog:C++17 i detaljer:Filsystem

Merged:The Mathematical Special Functions IS,

PDF - WG21 P0226R1

Forbedring af std::pair og std::tuple

N4387

std::shared_mutex (untimed)

N4508

Variant

P0088R2

Variant er en typesikker forening, der vil rapportere fejl, når du vil have adgang til noget, der ikke er inde i objektet i øjeblikket.

Bemærkninger:

  • Varianten har ikke tilladelse til at allokere yderligere (dynamisk) hukommelse.
  • En variant er ikke tilladt at indeholde referencer, arrays eller typetomheden.
  • En variant initialiseres som standard med værdien af ​​dets første alternativ.
  • Hvis den første alternative type ikke er standard konstruerbar, skal varianten bruge std::monostate som det første alternativ

Se flere eksempler i en separat artikel:
C++17 i detaljer:Standard Library Utilities ->Variant

  • cppreference/variant
  • IsoCpp:The Variant Saga:En lykkelig slutning?

Splejsning af kort og sæt

P0083R2

Fra Herb Sutter, Oulu turrapport:

Bidragydere

Dette er et sted for dig at blive nævnt!

Bidragydere:

  • Simon Brand
  • Jonathan Boccara, Flydende{C++}
  • Marek Kurdej
  • forslag fra r/cpp-tråden:c_17_features

Oversigt

Tak for al støtten med listen!

Der er stadig elementer, der bør opdateres, men listen er for det meste færdig.