Bonjour, cher lecteur!
Cet article est le premier d'une série d'articles abstraits que j'écrirai en lisant le livre de Scott Meyers, Effective and Modern c ++. Chacun de ces articles aura un répertoire distinct dans un projet spécialement mis en place sur github.com avec des exemples d'utilisation des fonctionnalités et techniques décrites.
Inférence de type de modÚle
Une conception réussie, c'est lorsque le consommateur ne sait pas comment fonctionne l'appareil, mais que tout lui convient.
La conclusion du type de modĂšle est lorsqu'il existe une fonction de modĂšle, par exemple, et qu'elle est appelĂ©e sans modĂšle ni parenthĂšses angulaires. En mĂȘme temps, le compilateur devine quel type il devra utiliser dans un objet particulier de la fonction.
Meyers divise le type - "T" , qui est affiché et le type - "ParamType" , qui est prescrit par le programmeur dans la définition du paramÚtre.
1. Vue des paramĂštres - lien ou pointeur
Afin de comprendre rapidement la rÚgle de dérivation, je vais la refléter sous la forme d'un modÚle:
type d'entrée -> type, paramÚtre -> type de sortie [, type final de paramÚtre ]
Exemple avec un lien:
template<typename T> // T void func(T& param) // - T& int x = 0; // int func(x);
Lorsque le type T est dérivé, la référentialité (*, &) est rejetée car elle est déjà indiquée lors de la définition de la fonction, comme si cela signifie "vous passez quoi que ce soit là , nous supposerons que ce n'est pas un lien, car la référentialité est déjà ajoutée sur le lieu de consommation - dans notre fonction f "
Selon le mĂȘme principe, la constance est ignorĂ©e si elle est spĂ©cifiĂ©e dans le paramĂštre de fonction. Sur les liens, pointeurs, constance, pour ainsi dire, un masque exclusif est imposĂ©.
Schéma de retrait
// int â> (T & param) â> int; const int â> (T & param) â> const int; const int & â> (T & param) â> const int // int â> (const T & param) â> int; const int â> (const T & param) â> int; const int & â> (const T & param) â> int; // int * â> (T * param) â> int; const int â> (T * param) â> const int; const int * â> (T * param) â> const int; // int * â> (const T * param) â> int; const int â> (const T * param) â> int; const int * â> (const T * param) â> int;
2. Type d'argument - référence universelle
Scott mentionne que les liens universels seront examinĂ©s plus tard, donc les rĂšgles pour les paramĂštres qu'il divise ici en rvalue et lvalue doivent juste ĂȘtre rappelĂ©es avec peu de rĂ©flexion.
template<typename T> void func(const T&& param)
RÚgles d'inférence pour lvalue
Selon Scott, c'est le seul cas oĂč T est sorti comme rĂ©fĂ©rence.
Dans les exemples suivants, le type du paramÚtre dans la description de la fonction est une référence lvalue universelle . On peut voir que T est affiché sous forme de lien ou de lien constant, selon
Ă partir de l'argument d'entrĂ©e, le type du paramĂštre param lui-mĂȘme est Ă©galement une rĂ©fĂ©rence dans ce cas.
lvalue int â> (T &¶m) â> int &, param - int& lvalue const int â> (T &¶m) â> const int &, param - const int& lvalue const int & â> (T &¶m) â> const int &, param - const int&
Le type du paramĂštre lui-mĂȘme est Ă©galement remplacĂ©. Je pense que cela est dĂ» au fait que le langage ne peut pas considĂ©rer une variable de valeur allouĂ©e quelque part au-dessus de celle qui peut ĂȘtre dĂ©placĂ©e plus loin. Nous le dĂ©couvrirons plus tard lorsque nous arriverons aux liens universels.
Pour vérifier que T est vraiment un type de référence, j'ai écrit T myVar dans le corps de la fonction de modÚle, que ce T a à la fois affiché et a attendu un message - "déclaré comme référence mais non initialisé" - le lien :)
RÚgles d'inférence pour rvalue
Les rÚgles «normales» du paragraphe 1 s'appliquent.
rvalue int â> (T &¶m) â> int, param - int&&
Il est déjà évident que les références universelles ne sont «incluses» que pour les objets temporaires rvalue, dans d'autres cas, lorsque l'argument n'est pas une référence universelle, rvalue, lvalue n'est pas distingué
3. Passez par valeur (tel quel)
Lors du passage par valeur, la constance et la référentialité de l'argument d'origine sont rejetées comme inutiles car ce sont des objets indépendants complÚtement nouveaux, pourquoi ont-ils besoin de qualificatifs avec lesquels ils ne sont pas connectés?
int â> (T param) â> int const int â> (T param) â> int const int & â> (T param) â> int
Je suppose que d'autres combinaisons folles et illogiques provoqueront des erreurs de compilation, presque toujours, il s'avÚre, le travail du compilateur est compréhensible, vous n'avez besoin d'écouter ces explications qu'une seule fois.