176 votes

Mot-clé automatique C++. Pourquoi est-il magique ?

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

Soudain, les itérateurs STL et, en fait, tout ce qui utilise des templates est dix fois plus facile à écrire. J'ai l'impression d'utiliser un langage "amusant" comme Python.

Où est passé ce mot-clé pendant toute ma vie ? Allez-vous briser mes rêves en disant que c'est exclusif à Visual Studio ou que ce n'est pas portable ?

22 votes

Ce n'est pas magique. C'est nouveau ( oh noes, quel mauvais jeu de mots ). Maintenant, l'asynchronisme est l'avenir ( halètement )

2 votes

Voici la référence sur les mots-clés automobiles fr.cppreference.com/w/cpp/language/auto

180voto

Jerry Coffin Points 237758

auto était un mot-clé que le C++ avait "hérité" du C, qui existait depuis presque toujours, mais qui n'était pratiquement jamais utilisé parce qu'il n'y avait que deux conditions possibles : soit il n'était pas autorisé, soit il était supposé par défaut.

L'utilisation de auto pour signifier un type déduit était nouveau avec C++11.

En même temps, auto x = initializer déduit le type de x du type de initializer de la même manière que la déduction du type de modèle fonctionne pour les modèles de fonction. Considérons 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é à T en fonction de la valeur passée 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 x du type de initializer qui est utilisé 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 dans tous les compilateurs qui ont essayé d'implémenter C++98/03. En tant que tel, l'ajout du support pour auto a été apparemment assez facile pour la plupart des équipes de compilateurs - il a été ajouté assez rapidement, et il semble qu'il y ait eu peu de bogues liés à lui aussi.

Lorsque cette réponse a été écrite à l'origine (en 2011, avant que l'encre ne sèche sur la norme C++ 11) auto était déjà assez portable. Aujourd'hui, il est parfaitement portable parmi tous les compilateurs courants. Les seules raisons évidentes de l'éviter seraient si vous devez é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 supporte pas (par exemple, quelques personnes écrivent encore du code pour MS-DOS en utilisant des compilateurs de Borland, Watcom, etc. qui n'ont pas connu de mises à jour significatives depuis des décennies). Si vous utilisez une version raisonnablement actuelle de l'un des compilateurs les plus courants, il n'y a aucune raison de l'éviter.

Les révisions plus récentes de la norme ont ajouté quelques nouveaux endroits qui auto peut être utilisé. À partir de C++14, vous pouvez utiliser auto pour le type d'un paramètre d'un lambda :

    [](auto s) { return s + 1; }

Il s'agit essentiellement de la même chose que dans l'exemple ci-dessus, même s'il n'utilise pas explicitement l'option template il s'agit essentiellement d'un modèle qui déduit le type du paramètre et instancie le modèle sur ce type.

C'était suffisamment pratique et utile pour qu'en C++20, la même capacité soit ajoutée aux fonctions normales, et pas seulement aux lambdas.

Mais, comme précédemment, tout cela revient à utiliser le même mécanisme de déduction de type de base que celui dont nous disposons pour les modèles de fonctions depuis C++98. auto permet de l'utiliser dans un plus grand nombre d'endroits et de manière plus pratique, mais le travail de fond reste le même.

0 votes

Depuis C++20, il est également possible d'utiliser la fonction auto comme un type de paramètre de fonction .

27voto

Nicol Bolas Points 133791

Il s'agit simplement de prendre un mot-clé généralement inutile et de lui donner une nouvelle et meilleure fonctionnalité. C'est un standard dans C++11, et la plupart des compilateurs C++ supportant un tant soit peu C++11 le supporteront.

1 votes

Oh ! Aha, je n'avais jamais pensé que le langage C++ était une chose qui pouvait changer en soi. Je vais devoir chercher ce qu'ils ont ajouté dans ce C++11, j'ai un peu entendu parler d'un C++0x mais je n'ai jamais creusé trop profondément dedans.

8 votes

@Clairvoire C++0x était le nom provisoire. Il a été publié ce mois-ci, et est donc devenu C++11.

18voto

Prathamesh Aware Points 326

Pour les variables, spécifie que le type de la variable déclarée sera automatiquement déduit de son initialisateur. Pour les fonctions, spécifie que le type de retour est un type de retour de fin de ligne ou sera déduit de ses déclarations 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 du bloc, dans la portée de l'espace de nom, dans les déclarations d'initialisation des boucles for, etc., le mot clé auto peut être utilisé comme spécificateur de type.

    Une fois le type de l'initialisateur déterminé, le compilateur détermine le type qui remplacera le mot-clé auto en utilisant les règles de déduction des arguments de modèle à partir d'un appel de fonction (voir déduction des arguments 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 du 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 l'appel de fonction f(expr) a été compilé. Par conséquent, auto&& peut être déduit soit comme une référence lvalue ou rvalue selon l'initialisateur, 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, alors que la déclaration auto i = 0, *p = &i; est bien formé et l'auto est déduit comme int.

  2. Dans une déclaration de fonction qui utilise la syntaxe du type de retour arrière, le mot clé auto n'effectue pas de détection automatique du type. Il sert uniquement de partie de la syntaxe.

  3. Dans une déclaration de fonction qui n'utilise pas la syntaxe de type de retour de fin, le mot clé auto indique que le type de retour sera déduit de l'opérande de sa déclaration 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 initialisateur, 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 de retour, et le type de retour réel est déduit en utilisant les règles de decltype.

  6. Un nested-name-specifier de la forme auto: : est un placeholder qui est remplacé par un type de classe ou d'énumération suivant les règles de déduction des placeholder 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. Mélanger des variables auto et des fonctions dans une même 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

13voto

Cette fonctionnalité n'a pas été là toute votre vie. Elle est prise en charge par Visual Studio depuis la version 2010. C'est une nouvelle fonctionnalité C++11, donc elle n'est pas exclusive à Visual Studio et elle est/serait portable. La plupart des compilateurs la prennent déjà en charge.

8voto

east1000 Points 266

Le mot clé auto est un mot clé important et fréquemment utilisé en C++. Lors de l'initialisation d'une variable, le mot clé auto est utilisé pour l'inférence de type (également appelée déduction de type).

Il existe 3 règles différentes concernant le mot-clé automobile.

Première règle

auto x = expr; ----> Pas de pointeur ou de référence, seulement un nom de variable. Dans ce cas, const et reference sont ignorés.

int  y = 10;
int& r = y;
auto x = r; // The type of variable x is int. (Reference Ignored)

const int y = 10;
auto x = y; // The type of variable x is int. (Const Ignored)

int y = 10;
const int& r = y;
auto x = r; // The type of variable x is int. (Both const and reference Ignored)

const int a[10] = {};
auto x = a; //  x is const int *. (Array to pointer conversion)

Note : When the name defined by auto is given a value with the name of a function,
       the type inference will be done as a function pointer.

Deuxième règle

auto& y = expr; o auto* y = expr; ----> Référence ou pointeur après le mot clé auto.

Avertissement : la constance n'est pas ignorée dans cette règle ! !! .

int y = 10;
auto& x = y; // The type of variable x is int&.

Avertissement : Dans cette règle, la conversion de tableau en pointeur (array decay) n'a pas lieu ! !!.

auto& x = "hello"; // The type of variable x is  const char [6].

static int x = 10;
auto y = x; // The variable y is not static.Because the static keyword is not a type. specifier 
            // The type of variable x is int.

Troisième règle

auto&& z = expr; ----> Il ne s'agit pas d'une référence Rvalue.

Avertissement : Si l'inférence de type est en cause et que le jeton && est utilisé, les noms introduits de la sorte sont appelés "référence de renvoi" (également appelée référence universelle).

auto&& r1 = x; // The type of variable r1 is int&.Because x is Lvalue expression. 

auto&& r2 = x+y; // The type of variable r2 is int&&.Because x+y is PRvalue expression.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X