Recherche…


Remarques

En novembre 2014, le Comité de normalisation C ++ a adopté la proposition N3922, qui élimine la règle de déduction de type spécial pour les initialiseurs automatiques et couplés à l'aide de la syntaxe d'initialisation directe. Cela ne fait pas partie du standard C ++ mais a été implémenté par certains compilateurs.

Déduction du paramètre de modèle pour les constructeurs

Avant C ++ 17, la déduction de modèle ne peut pas déduire le type de classe pour vous dans un constructeur. Il doit être explicitement spécifié. Parfois, cependant, ces types peuvent être très encombrants ou (dans le cas de lambdas) impossibles à nommer, nous avons donc eu une prolifération de types de fabriques (comme make_pair() , make_tuple() , back_inserter() , etc.).

C ++ 17

Ce n'est plus necessaire:

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)>

Les constructeurs sont supposés déduire les paramètres du modèle de classe, mais dans certains cas, cela est insuffisant et nous pouvons fournir des guides de déduction explicites:

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>

Déduction de type de modèle

Syntaxe générique du modèle

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

f(expr);

Cas 1: ParamType est une référence ou un pointeur, mais pas une référence universelle ou directe. Dans ce cas, la déduction de type fonctionne de cette façon. Le compilateur ignore la partie de référence si elle existe dans expr . Le compilateur alors Patronniers matchs expr de type s » contre ParamType à DETERMINATION 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&

Cas 2: ParamType est une référence universelle ou une référence directe. Dans ce cas, la déduction de type est la même que dans le cas 1 si expr est une valeur. Si expr est une lvalue, T et ParamType sont tous deux des références lvalue.

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&&

Cas 3: ParamType est ni un pointeur ni une référence. Si expr est une référence, la partie de référence est ignorée. Si expr est const, elle est également ignorée. S'il est volatile, il est également ignoré lors de la déduction du type de 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

Déduction automatique du type

C ++ 11

La déduction de type à l'aide du mot auto clé auto presque identique à la déduction de type de modèle. Voici quelques exemples:

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&&

Les différences sont décrites ci-dessous:

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>

Comme vous pouvez le voir si vous utilisez des initialiseurs à contreventement, auto est forcé de créer une variable de type std::initializer_list<T> . S'il ne peut pas déduire le de T , le code est rejeté.

Lorsque auto est utilisé comme type de retour d'une fonction, il spécifie que la fonction a un type de retour de fin .

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

C ++ 14 permet, en plus des utilisations d'auto autorisées dans C ++ 11, les suivantes:

  1. Lorsqu'il est utilisé comme type de retour d'une fonction sans type de retour final, spécifie que le type de retour de la fonction doit être déduit des instructions de retour dans le corps de la fonction, le cas échéant.

    // f returns int:
    auto f() { return 42; }
    // g returns void:
    auto g() { std::cout << "hello, world!\n"; }
    
  2. Lorsqu'il est utilisé dans le type de paramètre d'un lambda, définit le lambda comme étant un lambda générique .

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

La forme spéciale decltype(auto) déduit un type en utilisant les règles de déduction de type de decltype plutôt que celles de auto .

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

En C ++ 03 et versions antérieures, le mot auto clé auto avait une signification complètement différente en tant que spécificateur de classe de stockage hérité de C.



Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow