Maison > développement back-end > Tutoriel C#.Net > La différence et la connexion entre auto et decltype dans les nouvelles fonctionnalités de C 11

La différence et la connexion entre auto et decltype dans les nouvelles fonctionnalités de C 11

高洛峰
Libérer: 2017-01-23 14:34:32
original
1771 Les gens l'ont consulté

La différence et la connexion entre auto et decltype dans les nouvelles fonctionnalités de C 11

1 Introduction à auto

Lors de la programmation, vous devez souvent payer la valeur d'un. expression à une variable, et vous devez déclarer la variable pour savoir clairement de quel type est la variable. Cependant, ce n'est pas facile à faire (surtout dans les modèles), et parfois ce n'est pas possible du tout. Afin de résoudre ce problème, la nouvelle norme C 11 a introduit le spécificateur de type automatique, qui permet au compilateur d'analyser le type de l'expression pour nous. Il est différent de ceux d'origine qui correspondent uniquement à un spécificateur de type spécifique (tel que int). auto permet au compilateur d'effectuer une déduction de type via les valeurs initiales. Ainsi, le type de la variable définie est obtenu, donc la variable définie par auto doit avoir une valeur initiale.

//由val_1 和val_2相加的结果可以推断出item的类型
auto item = val_1 + val_2;//item 类型初始化为val_1 + val_2相加后的类型,值为val_1+val_2相加的值。
Copier après la connexion

Le type d'élément ici est calculé par le compilateur en ajoutant les types de val_1 et val_2 pendant le processus de compilation. S'il s'agit de val_1(int) val_2(double), alors le type d'élément est double.

Utilisez auto pour déclarer plusieurs variables dans une seule instruction, car un vêtement de pluie déclaré ne peut avoir qu'une seule donnée de base. type, donc le type de données de base initial de toutes les variables de l'équipement de pluie doit être le même. Assurez-vous de faire la distinction entre les types de données et les modificateurs de type ici ! !

int i = 3;
auto a = i,&b = i,*c = &i;//正确: a初始化为i的副本,b初始化为i的引用,c为i的指针.
auto sz = 0, pi = 3.14;//错误,两个变量的类型不一样。
Copier après la connexion

Le type automatique déduit par le compilateur n'est parfois pas exactement le même que le type de la valeur initiale. Le compilateur modifiera de manière appropriée le type de résultat pour le rendre plus cohérent avec. les règles d'initialisation.

Tout d'abord, comme nous le savons tous, utiliser une référence, c'est en fait utiliser l'objet référencé. Surtout lorsque la référence est utilisée comme valeur initiale, ce qui participe réellement à l'initialisation est la valeur de l'objet référencé. objet. À ce stade, le compilateur utilise le type de l'objet de référence comme type d'auto :

int i = 0 ,&r = i;//定义一个整数i,并且定义r为i的应用.
auto a = r; //这里的a为为一个整数,其值跟此时的i一样.
Copier après la connexion

On peut voir que auto ignorera la référence. Deuxièmement, auto le fera généralement. ignorez la const de niveau supérieur, mais la const sous-jacente sera conservée, par exemple lorsque la valeur initiale est un pointeur vers une constante :

int i = 0;
const int ci = i, &cr = ci; //ci 为整数常量,cr 为整数常量引用 
auto a = ci;   // a 为一个整数, 顶层const被忽略
auto b = cr;   // b 为一个整数,顶层const被忽略
auto c = &ci;  // c 为一个整数指针.
auto d = &cr;  // d 为一个指向整数常量的指针(对常量对象区地址是那么const会变成底层const)
Copier après la connexion

Si vous souhaitez déduire que le le type auto est une const de niveau supérieur, vous devez le signaler explicitement :

const auto f = ci;
Copier après la connexion

Vous pouvez également définir le type de référence sur auto, auquel cas les règles d'initialisation d'origine sont toujours apply (les const utilisés pour les déclarations de référence sont tous des const sous-jacents) :

auto &g = ci; //g是一个整数常量引用,绑定到ci。
auto &h = 42; // 错误:非常量引用的初始值必须为左值。
const auto &j = 42; //正确:常量引用可以绑定到字面值。
Copier après la connexion

2. Introduction à decltype

Parfois, nous rencontrerons cette situation Nous voulons déduire. le type de variable à définir à partir de l'expression, mais mais Vous ne souhaitez pas initialiser la variable avec la valeur de l'expression. Il est également possible que le type de retour de la fonction soit le type valeur d'une expression. Auto est impuissant dans ces moments-là, c'est pourquoi C 11 introduit un deuxième spécificateur de type, decltype, qui est utilisé pour sélectionner et renvoyer le type de données de l'opérande. Au cours de ce processus, le compilateur analyse uniquement l'expression et obtient son type, mais ne calcule pas réellement la valeur de l'expression.

decltype(f()) sum = x;// sum的类型就是函数f的返回值类型。
Copier après la connexion

Ici, le compilateur n'appelle pas réellement la fonction f, mais analyse la valeur de retour de la fonction f comme type de somme défini.

Fondamentalement, la fonction de decltype est très similaire à celle de auto, je ne les listerai donc pas un par un. Une autre utilisation de decltype est le type de retour postfix introduit dans c11.

3. La différence entre decltype et auto

La façon dont decltype gère la const et les références de niveau supérieur est légèrement différente de auto Si l'expression utilisée par decltype est une variable, decltype renvoie le type. de la variable (y compris la const de niveau supérieur et les références).

const int ci = 42, &cj = ci;
  
decltype(ci) x = 0;  // x 类型为const int
auto z = ci;     // z 类型为int
  
decltype(cj) y = x;  // y 类型为const int&
auto h = cj;     // h 类型为int
Copier après la connexion

Il y a certaines choses à noter à propos de decltype. Jetons d'abord un coup d'œil au code suivant :

int i = 42, *p = &i, &r = i;
  
decltype(i) x1 = 0;    //因为 i 为 int ,所以 x1 为int
auto x2 = i;       //因为 i 为 int ,所以 x2 为int
  
decltype(r) y1 = i;    //因为 r 为 int& ,所以 y1 为int&
auto y2 = r;       //因为 r 为 int& ,但auto会忽略引用,所以 y2 为int
  
decltype(r + 0) z1 = 0;  //因为 r + 0 为 int ,所以 z1 为int,
auto z2 = r + 0;     //因为 r + 0 为 int ,所以 z2 为int,
  
decltype(*p) h1 = i;   //这里 h1 是int&, 原因后面讲
auto h2 = *p;       // h2 为 int.
Copier après la connexion

Si le contenu de l'expression est une opération de déréférencement, decltype le fera. Obtenez le type de référence. Comme nous le savons, le déréférencement d’un pointeur peut faire pointer l’objet par le pointeur, et nous pouvons également attribuer une valeur à cet objet. Par conséquent, le type de résultat de decltype(*p) est int&.

Une autre différence importante entre decltype et auto est que le type de résultat de decltype est étroitement lié à la forme d'expression. Il existe une situation qui nécessite une attention particulière : pour l'expression utilisée par decltype, si une paire de parenthèses est ajoutée au nom de la variable, le type obtenu peut être différent de celui sans parenthèses. Si decltype utilise une variable sans parenthèses, le résultat est le type de la variable. Mais si vous ajoutez une ou plusieurs couches de parenthèses à cette variable, le compilateur traitera cette variable comme une expression. La variable est une expression spéciale qui peut être utilisée comme lvalue, donc un tel decltype renverra le type de référence :

.
int i = 42;
  
//decltype(i)  int 类型
//decltype((i)) int& 类型
Copier après la connexion


这里再指出一个需要注意的地方就是 = 赋值运算符返回的是左值的引用。换句话意思就是说 decltype(i = b) 返回类型为 i 类型的引用。仔细看下面这段代码:

int main()
{
  int i = 42;
  
  decltype(i = 41) x = i;
  
  auto y = i;
  
  auto& z = i;
  
  printf("i x y z 此时为: %d %d %d %d\n", i,x,y,z);
  
  i--;
  
  printf("i x y z 此时为: %d %d %d %d\n", i, x, y, z);
  
  x--;
  
  printf("i x y z 此时为: %d %d %d %d\n", i, x, y, z);
  
  y--;
  
  printf("i x y z 此时为: %d %d %d %d\n", i, x, y, z);
  
  z--;
  
  printf("i x y z 此时为: %d %d %d %d\n", i, x, y, z);
  
  return 0;
}
Copier après la connexion


运行结果为:

i x y z 此时为: 42 42 42 42
i x y z 此时为: 41 41 42 41
i x y z 此时为: 40 40 42 40
i x y z 此时为: 40 40 41 40
i x y z 此时为: 39 39 41 39
Copier après la connexion

   

     由上面的代码和运行结果可以看出来,1.decltype(i = 41)中的赋值语句并没有真正的运行。2. decltype(i = 41)返回的其实是int&,也就是说x 其实是 i 的引用。

了解了auto 和 decltype后,以后在使用的过程中一定要分清两者的区别,防止在定义的时候产生const 与非const 以及引用 与非引用 的差别!!

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

更多C++11新特性中auto 和 decltype 区别和联系相关文章请关注PHP中文网!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal