Zoeken…


Opmerkingen

In november 2014 keurde het C ++ Standaardisatiecomité voorstel N3922 goed, dat de speciale aftrekregel voor automatische en schrap initialisatoren elimineert met behulp van directe initialisatiesyntaxis. Dit maakt geen deel uit van de C ++ standaard maar is door sommige compilers geïmplementeerd.

Sjabloonparameteraftrek voor constructeurs

Voorafgaand aan C ++ 17 kan sjabloonaftrek het klasse-type niet voor u afleiden in een constructor. Het moet expliciet worden gespecificeerd. Soms kunnen deze typen echter erg omslachtig zijn of (in het geval van lambdas) onmogelijk te noemen, dus kregen we een proliferatie van make_pair() zoals make_pair() , make_tuple() , back_inserter() , etc.).

C ++ 17

Dit is niet langer nodig:

std::pair p(2, 4.5);     // std::pair<int, double>
std::tuple t(4, 3, 2.5); // std::tuple<int, int, double>
std::copy_n(vi1.begin(), 3,
    std::back_insert_iterator(vi2)); // constructs a back_insert_iterator<std::vector<int>>
std::lock_guard lk(mtx); // std::lock_guard<decltype(mtx)>

Constructeurs worden geacht de parameters van de klassensjabloon af te leiden, maar in sommige gevallen is dit onvoldoende en kunnen we expliciete deductiegidsen bieden:

template <class Iter>
vector(Iter, Iter) -> vector<typename iterator_traits<Iter>::value_type>

int array[] = {1, 2, 3};
std::vector v(std::begin(array), std::end(array)); // deduces std::vector<int>

Sjabloontype Aftrek

Sjabloon generieke syntaxis

template<typename T>
void f(ParamType param);

f(expr);

Geval 1: ParamType is een referentie of aanwijzer, maar geen universele of voorwaartse referentie. In dit geval werkt typeaftrek op deze manier. De compiler negeert het referentiedeel als het in expr bestaat. De compiler dan patroon-wedstrijden expr het type 's tegen ParamType op de aanwijzing T .

template<typename T>
void f(T& param);      //param is a reference

int x = 27;            // x is an int
const int cx = x;      // cx is a const int
const int& rx = x;     // rx is a reference to x as a const int

f(x);                  // T is int, param's type is int&
f(cx);                 // T is const int, param's type is const int&
f(rx);                 // T is const int, param's type is const int&

Geval 2: ParamType is een Universal Reference of Forward Reference. In dit geval is de type-aftrek hetzelfde als in geval 1 als de expr is. Als expr is, worden zowel T als ParamType afgeleid als ParamType .

template<typename T>
void f(T&& param);     // param is a universal reference

int x = 27;            // x is an int
const int cx = x;      // cx is a const int
const int& rx = x;     // rx is a reference to x as a const int

f(x);                  // x is lvalue, so T is int&, param's type is also int&
f(cx);                 // cx is lvalue, so T is const int&, param's type is also const int&
f(rx);                 // rx is lvalue, so T is const int&, param's type is also const int&
f(27);                 // 27 is rvalue, so T is int, param's type is therefore int&&

Geval 3: ParamType is noch een aanwijzer noch een referentie. Als expr een referentie is, wordt het referentiedeel genegeerd. Als expr const is, wordt dat ook genegeerd. Als het vluchtig is, wordt dat ook genegeerd bij het afleiden van het type van T.

template<typename T>
void f(T param);       // param is now passed by value

int x = 27;            // x is an int
const int cx = x;      // cx is a const int
const int& rx = x;     // rx is a reference to x as a const int

f(x);                  // T's and param's types are both int
f(cx);                 // T's and param's types are again both int
f(rx);                 // T's and param's types are still both int

Auto Type Aftrek

C ++ 11

Type aftrek met behulp van het auto trefwoord werkt bijna hetzelfde als Sjabloon Type aftrek. Hieronder enkele voorbeelden:

auto x = 27;           // (x is neither a pointer nor a reference), x's type is int
const auto cx = x;     // (cx is neither a pointer nor a reference), cs's type is const int
const auto& rx = x;    // (rx is a non-universal reference), rx's type is a reference to a const int

auto&& uref1 = x;      // x is int and lvalue, so uref1's type is int&
auto&& uref2 = cx;     // cx is const int and lvalue, so uref2's type is const int &
auto&& uref3 = 27;     // 27 is an int and rvalue, so uref3's type is int&&

De verschillen worden hieronder beschreven:

auto x1 = 27;          // type is int, value is 27
auto x2(27);           // type is int, value is 27
auto x3 = { 27 };      // type is std::initializer_list<int>, value is { 27 }
auto x4{ 27 };         // type is std::initializer_list<int>, value is { 27 }
                       // in some compilers type may be deduced as an int with a 
                       // value of 27. See remarks for more information.
auto x5 = { 1, 2.0 }   // error! can't deduce T for std::initializer_list<t>

Zoals je kunt zien als je accolades gebruikt, wordt auto gedwongen een variabele van het type std::initializer_list<T> . Als het niet uit T kan afleiden, wordt de code afgewezen.

Wanneer auto wordt gebruikt als het retourtype van een functie, geeft dit aan dat de functie een volgend retourtype heeft .

auto f() -> int {
    return 42;
}
C ++ 14

C ++ 14 staat, naast het gebruik van auto toegestaan in C ++ 11, het volgende toe:

  1. Wanneer het wordt gebruikt als het retourtype van een functie zonder een volgend retourtype, geeft dit op dat het retourtype van de functie moet worden afgeleid uit de retourinstructies in de hoofdtekst van de functie, indien aanwezig.

    // f returns int:
    auto f() { return 42; }
    // g returns void:
    auto g() { std::cout << "hello, world!\n"; }
    
  2. Wanneer gebruikt in het parametertype van een lambda, definieert de lambda een generieke lambda .

    auto triple = [](auto x) { return 3*x; };
    const auto x = triple(42); // x is a const int with value 126
    

De speciale vorm decltype(auto) leidt een type af met behulp van de regels voor decltype van decltype plaats van die van auto .

int* p = new int(42);
auto x = *p;           // x has type int
decltype(auto) y = *p; // y is a reference to *p

In C ++ 03 en eerder had het auto sleutelwoord een heel andere betekenis als een opslagklasse-aanduiding die werd overgenomen van C.



Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow