Mot-clé auto C ++. Pourquoi est-ce magique?

145

De tout le matériel que j'ai utilisé pour apprendre le C ++, autoa toujours été un spécificateur de durée de stockage étrange qui ne servait à rien. Mais récemment, j'ai rencontré du code qui l'utilisait comme nom de type en soi. Par curiosité, je l'ai essayé, et cela suppose le type de tout ce que je lui attribue!

Tout à coup, les itérateurs STL et, enfin, tout ce qui utilise des modèles est 10 fois plus facile à écrire. J'ai l'impression d'utiliser un langage `` amusant '' comme Python.

Où est ce mot-clé toute ma vie? Allez-vous anéantir mes rêves en disant que c'est exclusif à Visual Studio ou non portable?

Anne Quinn
la source
18
ce n'est pas. la magie. C'est nouveau ( oh non, quel mauvais jeu de mots ). Il est maintenant async l'avenir ( halètement )
sehe
2
Voici la référence sur les mots-clés auto en.cppreference.com/w/cpp/language/auto
andyqee

Réponses:

150

auto était un mot-clé que C ++ "héritait" de C qui était là depuis presque toujours, mais pratiquement jamais utilisé car il n'y avait que deux conditions possibles: soit il n'était pas autorisé, soit il était supposé par défaut.

L'utilisation de autopour signifier un type déduit était nouvelle avec C ++ 11.

Dans le même temps, auto x = initializerdéduit le type de xdu type de initializerla même manière que la déduction du type de modèle fonctionne pour les modèles de fonction. Considérez un modèle de fonction comme celui-ci:

template<class T>
int whatever(T t) { 
    // point A
};

Au point A, un type a été attribué à en Tfonction de la valeur transmise pour le paramètre à whatever. Lorsque vous le faites auto x = initializer;, la même déduction de type est utilisée pour déterminer le type de à xpartir du type initializerutilisé pour l'initialiser.

Cela signifie que la plupart des mécanismes de déduction de type qu'un compilateur doit implémenter autoétaient déjà présents et utilisés pour les modèles sur n'importe quel compilateur qui tentait même d'implémenter C ++ 98/03. En tant que tel, l'ajout du support pour autoétait apparemment assez facile pour pratiquement toutes les équipes de compilateurs - il a été ajouté assez rapidement, et il semble y avoir eu peu de bogues liés à cela non plus.

Lorsque cette réponse a été écrite à l'origine (en 2011, avant que l'encre ne soit sèche sur la norme C ++ 11) autoétait déjà assez portable. De nos jours, il est parfaitement portable parmi tous les compilateurs grand public. Les seules raisons évidentes de l'éviter seraient si vous avez besoin d'écrire du code compatible avec un compilateur C, ou si vous avez un besoin spécifique de cibler un compilateur de niche dont vous savez qu'il ne le prend pas en charge (par exemple, quelques personnes écrivent encore du code pour MS-DOS utilisant des compilateurs de Borland, Watcom, etc., qui n'ont pas connu de mises à niveau significatives depuis des décennies). Si vous utilisez une version raisonnablement actuelle de l'un des compilateurs grand public, il n'y a aucune raison de l'éviter du tout.

Jerry Coffin
la source
24

Il s'agit simplement de prendre un mot-clé généralement inutile et de lui donner une nouvelle et meilleure fonctionnalité. Il est standard dans C ++ 11, et la plupart des compilateurs C ++ avec même un support C ++ 11 le prendront en charge.

Nicol Bolas
la source
Oh! Aha, je n'ai jamais pensé que le langage C ++ était quelque chose qui pouvait changer en soi. Je vais devoir chercher ce qu'ils ont ajouté d'autre dans ce C ++ 11, j'ai entendu un peu de C ++ 0x mais je n'ai jamais creusé trop profondément.
Anne Quinn
7
@Clairvoire C ++ 0x était le nom provisoire. Il a été publié ce mois-ci et est donc devenu C ++ 11.
R. Martinho Fernandes
13

Pour les variables, spécifie que le type de la variable qui est déclarée sera automatiquement déduit de son initialiseur. Pour les fonctions, spécifie que le type de retour est un type de retour de fin ou sera déduit de ses instructions de retour (depuis C ++ 14).

Syntaxe

auto variable initializer   (1) (since C++11)

auto function -> return type    (2) (since C++11)

auto function   (3) (since C++14)

decltype(auto) variable initializer (4) (since C++14)

decltype(auto) function (5) (since C++14)

auto :: (6) (concepts TS)

cv(optional) auto ref(optional) parameter   (7) (since C++14)

Explication

1) Lors de la déclaration de variables dans la portée de bloc, dans la portée de l'espace de noms, dans les instructions d'initialisation des boucles for, etc., le mot-clé auto peut être utilisé comme spécificateur de type. Une fois que le type de l'initialiseur a été déterminé, le compilateur détermine le type qui remplacera le mot-clé auto en utilisant les règles de déduction d'argument de modèle à partir d'un appel de fonction (voir Déduction d'argument de modèle # Autres contextes pour plus de détails). Le mot-clé auto peut être accompagné de modificateurs, tels que const ou &, qui participeront à la déduction de type. Par exemple, étant donné const auto& i = expr;, le type de i est exactement le type de l'argument u dans un modèle imaginaire template<class U> void f(const U& u)si la fonction appellef(expr)a été compilé. Par conséquent, auto && peut être déduit soit comme une référence lvalue, soit comme une référence rvalue selon l'initialiseur, qui est utilisé dans la boucle for basée sur la plage. Si auto est utilisé pour déclarer plusieurs variables, les types déduits doivent correspondre. Par exemple, la déclaration auto i = 0, d = 0.0;est mal formée, tandis que la déclaration auto i = 0, *p = &i;est bien formée et l'auto est déduite comme int.

2) Dans une déclaration de fonction qui utilise la syntaxe du type de retour de fin, le mot-clé auto n'effectue pas de détection de type automatique. Cela fait uniquement partie de la syntaxe.

3) Dans une déclaration de fonction qui n'utilise pas la syntaxe du type de retour de fin, le mot-clé auto indique que le type de retour sera déduit de l'opérande de son instruction de retour en utilisant les règles de déduction des arguments de modèle.

4) Si le type déclaré de la variable est decltype (auto), le mot-clé auto est remplacé par l'expression (ou la liste d'expressions) de son initialiseur, et le type réel est déduit en utilisant les règles de decltype.

5) Si le type de retour de la fonction est déclaré decltype (auto), le mot-clé auto est remplacé par l'opérande de son instruction return, et le type de retour réel est déduit en utilisant les règles de decltype.

6) Un spécificateur de nom imbriqué de la forme auto :: est un espace réservé qui est remplacé par un type de classe ou d'énumération suivant les règles de déduction d'espace réservé de type contraint.

7) Une déclaration de paramètre dans une expression lambda. (depuis C ++ 14) Une déclaration de paramètre de fonction. (concepts TS)

Notes Jusqu'à C ++ 11, auto avait la sémantique d'un spécificateur de durée de stockage. Le mélange de variables automatiques et de fonctions dans une seule déclaration, comme dans auto f() -> int, i = 0;n'est pas autorisé.

Pour plus d'informations: http://en.cppreference.com/w/cpp/language/auto

Prathamesh Aware
la source
11

Cette fonctionnalité n'a pas été là toute votre vie. Il est pris en charge dans Visual Studio depuis la version 2010. Il s'agit d'une nouvelle fonctionnalité C ++ 11, elle n'est donc pas exclusive à Visual Studio et est / sera portable. La plupart des compilateurs le prennent déjà en charge.

R. Martinho Fernandes
la source
3

Cela ne va nulle part ... c'est une nouvelle fonctionnalité C ++ standard dans l'implémentation de C ++ 11. Cela étant dit, bien que ce soit un outil formidable pour simplifier les déclarations d'objets ainsi que pour nettoyer la syntaxe de certains paradigmes d'appel (c'est-à-dire, les boucles for basées sur une plage), n'en abusez pas :-)

Jason
la source
3

Le mot clé auto spécifie que le type de la variable déclarée sera automatiquement déduit de son initialiseur. Dans le cas des fonctions, si leur type de retour est auto, cela sera évalué par l'expression de type de retour lors de l'exécution.

Cela peut être très utile lorsque nous devons utiliser l'itérateur. Par exemple, pour le code ci-dessous, nous pouvons simplement utiliser "auto" au lieu d'écrire toute la syntaxe de l'itérateur.

int main() 
{ 

// Initialize set 
set<int> s; 

s.insert(1); 
s.insert(4); 
s.insert(2); 
s.insert(5); 
s.insert(3); 

// iterator pointing to 
// position where 2 is 
auto pos = s.find(3); 

// prints the set elements 
cout << "The set elements after 3 are: "; 
for (auto it = pos; it != s.end(); it++) 
    cout << *it << " "; 

return 0; 
}

Voici comment nous pouvons utiliser le mot-clé "auto"

rahul goyal
la source
0

C'est magique, c'est sa capacité à réduire le besoin d'écrire du code pour chaque type de variable passé dans des fonctions spécifiques. Considérez une fonction print () similaire à Python dans sa base C.

#include <iostream>
#include <string>
#include <array>

using namespace std;

void print(auto arg) {
     cout<<arg<<" ";
}

int main()
{
  string f = "String";//tok assigned
  int x = 998;
  double a = 4.785;
  string b = "C++ Auto !";
//In an opt-code ASCII token stream would be iterated from tok's as:
  print(a);
  print(b);
  print(x);
  print(f);
}
rodéone2
la source