Combien coûte trop avec le mot clé automatique C ++ 11?

218

J'ai utilisé le nouveau automot clé disponible dans la norme C ++ 11 pour les types de modèles compliqués, ce pour quoi je pense qu'il a été conçu. Mais je l'utilise aussi pour des choses comme:

auto foo = std::make_shared<Foo>();

Et plus sceptiquement pour:

auto foo = bla(); // where bla() return a shared_ptr<Foo>

Je n'ai pas vu beaucoup de discussions sur ce sujet. Il semble que cela autopourrait être surutilisé, car un type est souvent une forme de documentation et de vérification de l'intégrité. Où tracez-vous la ligne d'utilisation autoet quels sont les cas d'utilisation recommandés pour cette nouvelle fonctionnalité?

Pour clarifier: je ne demande pas d'avis philosophique; Je demande l'utilisation prévue de ce mot-clé par le comité standard, éventuellement avec des commentaires sur la façon dont cette utilisation prévue est réalisée dans la pratique.

Note latérale: Cette question a été déplacée vers SE.Programmers, puis de nouveau vers Stack Overflow. Une discussion à ce sujet peut être trouvée dans cette méta-question .

Alan Turing
la source
Il s'agit cependant d'un site de questions / réponses, pas d'un site de discussion. Vous avez posé une question très très générale et je doute que quiconque puisse vous donner autre chose qu'une question très subjective. (c'est pourquoi -1)
TravisG
15
@heishe, j'ai ajouté une clarification. Si vous lisez la question de manière très générale, elle semble demander une opinion subjective, mais vraiment si vous avez utilisé le automot - clé, alors vous savez comment il est censé être utilisé. C'est ce que je demande, en tant que nouveau utilisateur de cette fonctionnalité, comment dois-je l'utiliser?
Alan Turing
13
J'ai vu cette discussion partout quand C # a été introduit var(c'est-à-dire, une fois que les gens ont fini par penser que ce n'était pas du typage dynamique après tout). Si vous le souhaitez, vous pouvez commencer par cette question et passer par les questions connexes.
R. Martinho Fernandes
2
@Lex: Quelque chose est légal ou non; qualifier quelque chose de «mauvais» de légal est subjectif par définition. C'est-à-dire que qualifier de auto foo = bla();«mauvais» est clairement une opinion, pas un fait, ce qui rend cette question et répond à une discussion, ce qui la rend pertinente pour Programmers SE, ce qui est exactement ce que les votes serrés indiquent. / haussement d'épaules
ildjarn
3
Herb Sutter vue à ce sujet: herbsutter.com/2013/06/13/…
rafak

Réponses:

131

Je pense que l'on devrait utiliser le automot - clé chaque fois qu'il est difficile de dire comment écrire le type à première vue, mais le type du côté droit d'une expression est évident. Par exemple, en utilisant:

my_multi_type::nth_index<2>::type::key_type::composite_key_type::
    key_extractor_tuple::tail_type::head_type::result_type

pour obtenir le type de clé composite boost::multi_index, même si vous savez qu'il l'est int. Vous ne pouvez pas simplement écrire intcar cela pourrait être changé à l'avenir. J'écrirais autodans ce cas.

Donc, si le automot clé améliore la lisibilité dans un cas particulier, utilisez-le. Vous pouvez écrire autoquand il est évident pour le lecteur quel type autoreprésente.

Voici quelques exemples:

auto foo = std::make_shared<Foo>();   // obvious
auto foo = bla();                     // unclear. don't know which type `foo` has

const size_t max_size = 100;
for ( auto x = max_size; x > 0; --x ) // unclear. could lead to the errors
                                      // since max_size is unsigned

std::vector<some_class> v;
for ( auto it = v.begin(); it != v.end(); ++it )
                                      // ok, since I know that `it` has an iterator type
                                      // (don't really care which one in this context)
Kirill V. Lyadvinsky
la source
18
Cela ne semble pas être une très bonne recommandation. À quelle fréquence est-ce que vous ne connaissez pas le type de l'objet? (En dehors des modèles, c'est-à-dire.) Et si vous ne savez pas qu'ils tapent, recherchez-le, ne soyez pas paresseux et utilisez auto.
Paul Manta
9
@Paul: souvent, vous ne connaissez ou n'avez besoin que de connaître la partie la plus importante du type, par exemple qu'il s'agit d'un itérateur, mais vous ne savez pas et ne vous souciez pas s'il s'agit d'un itérateur de vecteurs ou d'un itérateur de liens liste; dans ces cas, vous ne voulez vraiment pas passer du temps et de l'espace d'écran à essayer de comprendre comment écrire les types.
Lie Ryan
45
Que les purs et durs de C ++ l'aiment ou non, C ++ 0x attirera des gens qui n'auraient jamais utilisé C ++. Et ceux-ci utiliseront l'automobile partout.
Prof.Falken
6
@ R.MartinhoFernandes - non, la seule chose qui est claire est que tout ce quebla() vous donnez en retour foo.
Luis Machuca
8
@LuisMachuca ma réponse était une manière ironique de dire qu'il est malhonnête de donner un exemple de mauvais nom de variable et de fonction et de blâmer son manque de lisibilité sur l'inférence de type.
R. Martinho Fernandes
62

Utilisez-le autopartout où vous le pouvez, en particulier const autopour que les effets secondaires soient moins préoccupants. Vous n'aurez pas à vous soucier des types, sauf dans les cas évidents, mais ils seront toujours vérifiés statiquement pour vous, et vous pouvez éviter certaines répétitions. Lorsque cela auton'est pas possible, vous pouvez utiliser decltypepour exprimer des types sémantiquement sous forme de contrats basés sur des expressions. Votre code sera différent, mais ce sera un changement positif.

Jon Purdy
la source
12
Je dirais particulièrement «const auto &»
Viktor Sehr
2
Meilleure utilisation auto&&dans des situations complexes edmundv.home.xs4all.nl/blog/2014/01/28/…
KindDragon
2
@KindDragon: C'est une bonne règle de base, mais je préfère utiliser const auto&ou à const automoins que je veuille explicitement muter ou bouger.
Jon Purdy
" Utilisez auto partout où vous le pouvez ". Est-ce à dire que je devrais écrire à la auto str = std::string();place de std::string str;?
Calmarius
4
Utiliser auto partout rendra votre code moins lisible et plus difficile à déboguer car vous devrez déduire les types vous-même lors de la lecture du code.
SubMachine
52

Facile. Utilisez-le lorsque vous ne vous souciez pas du type. Par exemple

for (const auto & i : some_container) {
   ...

Tout ce qui m'importe ici, c'est ce qu'il iy a dans le conteneur.

C'est un peu comme les typedefs.

typedef float Height;
typedef double Weight;
//....
Height h;
Weight w;

Ici, je ne me soucie pas de savoir si het wsont des flotteurs ou des doubles, seulement qu'ils sont de tout type approprié pour exprimer les hauteurs et les poids .

Ou pensez

for (auto i = some_container .begin (); ...

Ici, tout ce qui m'importe, c'est que c'est un itérateur approprié, supportant operator++(), c'est un peu comme taper du canard à cet égard.

De plus, le type de lambdas ne peut pas être orthographié, tout auto f = []...comme le bon style. L'alternative est de lancer std::functionmais cela vient avec des frais généraux.

Je ne peux pas vraiment concevoir un "abus" de auto. Le plus proche que je peux imaginer est de vous priver d'une conversion explicite en un type significatif - mais vous ne l'utiliseriez pas autopour cela, vous construiriez un objet du type souhaité.

Si vous pouvez supprimer une certaine redondance dans votre code sans introduire d'effets secondaires, cela doit être bon de le faire.

Contre-exemples (empruntés aux réponses de quelqu'un d'autre):

auto i = SomeClass();
for (auto x = make_unsigned (y); ...)

Ici, nous nous soucions du type, nous devons donc écrire Someclass i;etfor(unsigned x = y;...

vaporiser
la source
1
Hum. Pas si facile. Il compile et s'exécute, et vous venez de vous tirer une balle dans le pied si les éléments sont des objets non triviaux - votre itération appelle le constructeur et le destructeur de copie à chaque étape de l'itération. Si vous allez utiliser aveuglément auto dans un itérateur basé sur une plage, il devrait probablement être "for (const auto & item: some_container)" au lieu de "for (auto item: some_container)".
Don Hatch,
2
Pas toujours, mais ok vous voulez probablement des références. Et alors? Ça n'a rien à voir auto.
pulvérisation
Je ne comprends vraiment pas votre dernier commentaire. J'ai essayé d'expliquer pourquoi votre stratégie ne me semble pas très bonne et pourquoi je la vote en aval.
Don Hatch
5
Je dis que si vous utilisez des références ou non est orthogonal à l'utilisation automatique ou non. Je vais le modifier pour ajouter la référence, car il est vrai que c'est généralement ce que l'on veut faire, mais cela n'a absolument rien à voir avec le sujet traité.
pulvérisation
43

Fonce. Utilisez-le autopartout où il facilite l'écriture de code.

Chaque nouvelle fonctionnalité dans n'importe quelle langue va être surutilisée par au moins certains types de programmeurs. Ce n'est que par une surutilisation modérée par certains programmeurs expérimentés (et non par des noobs) que le reste des programmeurs expérimentés apprend les limites d'une bonne utilisation. Une surutilisation extrême est généralement mauvaise, mais pourrait être bonne car une telle surutilisation peut conduire à des améliorations de la fonctionnalité ou à une meilleure fonctionnalité pour la remplacer.

Mais si je travaillais sur du code avec plus de quelques lignes comme

auto foo = bla();

où le type est indiqué zéro fois, je pourrais vouloir changer ces lignes pour inclure des types. Le premier exemple est excellent car le type est indiqué une fois, et autonous évite d'avoir à écrire deux fois des types malpropres. Hourra pour C ++++. Mais montrer explicitement le type zéro fois, s'il n'est pas facilement visible dans une ligne proche, me rend nerveux, au moins en C ++ et ses successeurs immédiats. Pour d'autres langages conçus pour fonctionner à un niveau supérieur avec plus d'abstraction, de polymorphisme et de généricité, c'est bien.

DarenW
la source
38

Au C ++ et au-delà de 2012 dans le panel Ask Us Anything , il y a eu un échange fantastique entre Andrei Alexandrescu, Scott Meyers et Herb Sutter pour savoir quand utiliser et ne pas utiliserauto . Passez à la minute 25:03 pour une discussion de 4 minutes. Les trois haut-parleurs donnent d'excellents points qui doivent être gardés à l'esprit pour savoir quand ne pas les utiliser auto.

J'encourage fortement les gens à arriver à leur propre conclusion, mais mon emport était de l' utiliser autopartout sauf si :

  1. Cela nuit à la lisibilité
  2. On s'inquiète de la conversion automatique de type (par exemple à partir de constructeurs, d'affectation, de types intermédiaires de modèle, de conversion implicite entre des largeurs entières)

L'utilisation libérale des explicitaides réduit la préoccupation pour ces derniers, ce qui contribue à minimiser la durée pendant laquelle les premiers sont un problème.

En reformulant ce que Herb a dit, "si vous ne faites pas X, Y et Z, utilisez auto. Apprenez ce que sont X, Y et Z et allez-y et utilisez autopartout ailleurs."

Sean
la source
4
Il vaut probablement aussi la peine de créer un
Rob Starling
37

Oui, il peut être abusé au détriment de la lisibilité. Je suggère de l'utiliser dans des contextes où les types exacts sont longs, ou inexprimables, ou non importants pour la lisibilité, et les variables sont de courte durée. Par exemple, le type d'itérateur est généralement long et n'est pas important, donc autofonctionnerait:

   for(auto i = container.begin(); i != container.end(); ++i);

auto ici ne nuit pas à la lisibilité.

Un autre exemple est le type de règle d'analyseur, qui peut être long et alambiqué. Comparer:

   auto spaces = space & space & space;

avec

r_and_t<r_and_t<r_char_t<char>&, r_char_t<char>&>, r_char_t<char>&> spaces = 
   space & space & space;

D'un autre côté, lorsque le type est connu et simple, c'est beaucoup mieux s'il indique explicitement:

int i = foo();

plutôt que

auto i = foo();
Gene Bushuyev
la source
2
Bien sûr, avoir une boucle basée sur une plage dans la langue rend votre premier exemple moins passionnant. 8v)
Fred Larson
@Fred: le type peut encore être encombrant (je pense aux conteneurs associatifs)
Matthieu M.
3
@Fred: Chaque fois que vos limites ne le sont pas begin()et end(), ou que la taille de votre pas est autre chose qu'un, ou que vous modifiez le conteneur pendant que vous bouclez, l'instruction basée sur la plage for ne vous aidera pas.
Dennis Zickefoose
6
@geotavros: Et le r_and_t<r_and_t<r_char_t<char>&, r_char_t<char>&>, r_char_t<char>&>fait?
Dennis Zickefoose
7
@geotavros: Ou vous pouvez voir de quel type il spaces'agit et rechercher cela. Ce sont les informations les plus utiles de toute façon ... après tout, le problème n'est pas "de quel type est cette nouvelle variable" mais plutôt "qu'est-ce que cela space & space & spacesignifie?" Le type réel de l'expression n'est que du bruit.
Dennis Zickefoose
19

auto peut être très dangereux en combinaison avec des modèles d'expression qui sont beaucoup utilisés par les bibliothèques d'algèbre linéaire telles que Eigen ou OpenCV.

auto A = Matrix(...);
auto B = Matrix(...);
auto C = A * B; // C is not a matrix. It is a matrix EXPRESSION.
cout << C; // The expression is evaluated and gives the expected result.
... // <code modifying A or B>
cout << C; // The expression is evaluated AGAIN and gives a DIFFERENT result.

Les bugs causés par ce type d'erreurs sont une difficulté majeure à déboguer. Un remède possible consiste à convertir explicitement le résultat dans le type attendu si vous êtes déterminé à utiliser auto pour le style de déclaration de gauche à droite.

auto C = Matrix(A * B); // The expression is now evaluated immediately.
morotspaj
la source
1
Cela semble être un comportement étrange pour commencer. Si je multiplie deux matrices, même si l'opération est paresseuse, je ne m'attendrais pas à ce qu'elle soit réévaluable, je m'attendrais à ce qu'elle maintienne son état évalué après l'évaluation initiale. Si vous souhaitez modifier les paramètres sans modifier les paramètres d'origine, ne finiriez-vous pas par avoir à reconstruire l'expression de toute façon? Ou est-il conçu pour une sorte de situation de traitement en streaming, où les paramètres d'origine changent constamment mais la procédure reste la même?
JAB
1
Que l' A*Bexpression soit copiée ou non dans une autovariable ou autre chose, le comportement que vous décrivez est toujours présent.
xtofl
Aucun bug n'est provoqué par l'utilisation auto.
Jim Balter
@JAB: Il est conçu pour prendre en charge les simplifications et les synergies entre les opérations, par exemple diag(A * B)n'a pas à gaspiller les cycles de calcul des éléments hors diagonale.
Ben Voigt
J'ai également repéré du code comme 'for (auto o: vecContainer)' où 'o' était un objet lourd qui est copié à chaque fois. Ma recommandation serait de l'utiliser pour ce à quoi il était initialement destiné, à savoir des modèles (avec des directives de déduction difficiles) et des typedef laborieux. Même alors, vous devez être prudent et faire la distinction entre auto et auto &.
gast128
10

J'utilise autosans restriction et je n'ai rencontré aucun problème. Je finis même parfois par l'utiliser pour des types simples comme int. Cela fait de c ++ un langage de niveau supérieur pour moi et permet de déclarer des variables en c ++ comme en python. Après avoir écrit du code python, j'écris même parfois par exemple

auto i = MyClass();

au lieu de

MyClass i;

C'est un cas où je dirais que c'est un abus du automot - clé.

Souvent, cela ne me dérange pas quel est le type exact de l'objet, je suis plus intéressé par sa fonctionnalité, et comme les noms de fonction disent généralement quelque chose sur les objets qu'ils retournent, autocela ne fait pas de mal: par exemple auto s = mycollection.size(), je peux deviner que ce ssera une sorte d'entier, et dans les rares cas où je me soucie du type exact, vérifions ensuite le prototype de la fonction (je veux dire, je préfère avoir à vérifier quand j'ai besoin des informations, plutôt qu'à priori lorsque le code est écrit, juste au cas où cela serait utile un jour, comme dans int_type s = mycollection.size()).

Concernant cet exemple de la réponse acceptée:

for ( auto x = max_size; x > 0; --x )

Dans mon code, j'utilise toujours autodans ce cas, et si je veux xêtre non signé, alors j'utilise une fonction utilitaire, nommée say make_unsigned, qui exprime clairement mes préoccupations:

for ( auto x = make_unsigned(max_size); x > 0; --x )

mentions légales: je viens de décrire mon utilisation, je ne suis pas compétent pour donner des conseils!

rafak
la source
1
@ChristianRau: n'était pas sarcastique. Notez que je n'ai pas recommandé l'utilisation auto i = MyClass().
rafak
3
Suivi: voir: herbsutter.com/2013/06/13/… . L'utilisation de par exemple as_unsignedest recommandée là-bas, ou même auto w = widget{};.
rafak
3

L'un des problèmes majeurs du programme C ++ est qu'il vous permet d'utiliser la variable non initialisée . Cela nous amène à un comportement de programme non déterministe désagréable. Il convient de noter que le compilateur moderne lance désormais des messages d'avertissement / message appropriés si le programme se lasse de l'utiliser.

Juste pour illustrer cela, considérez le programme c ++ ci-dessous:

int main() {
    int x;
    int y = 0;
    y += x;
}

Si je compile ce programme en utilisant un compilateur moderne (GCC), il donne l'avertissement. Un tel avertissement peut ne pas être très évident si nous travaillons avec le vrai code de production complexe.

main.cpp: Dans la fonction 'int main ()':

main.cpp: 4: 8: avertissement : 'x' est utilisé non initialisé dans cette fonction [-Wuninitialized]

y + = x;

    ^

================================================== =============================== Maintenant, si nous changeons notre programme qui utilise auto , puis compilons nous obtenons ce qui suit:

int main() {
    auto x;
    auto y = 0;
    y += x;
}

main.cpp: Dans la fonction 'int main ()':

main.cpp: 2: 10: erreur : la déclaration de 'auto x' n'a pas d'initialiseur

 auto x;

      ^

Avec auto, il n'est pas possible d'utiliser la variable non initialisée. C'est un avantage majeur que nous pouvons obtenir (gratuitement) si nous commençons à utiliser auto .

Ce concept et d'autres grands grands concepts C ++ modernes sont expliqués par Herb Shutter, expert C ++, dans son discours sur CppCon14 :

Retour à l'essentiel! Essentiels du style C ++ moderne

Mantosh Kumar
la source
2
Oui. Et pour spécifier le type que vous pouvez initialiser comme 0i, 0u, 0l, 0ul, 0.0f, 0.0, ou même int (), unsigned (), double (), etc.
Robinson
6
Cet argument est ridicule. Vous dites "vous ne pouvez pas oublier l'initialiseur car vous obtiendrez une erreur de compilation", mais cela vous oblige à ne pas oublier d'utiliser auto.
Courses de légèreté en orbite
1
@LightnessRacesinOrbit: J'ai réalisé (appris) ce concept à partir de l'entretien avec Herb Sutter. Je l'ai trouvé logique / pratique dans les discussions sur les herbes, donc j'ai pensé le partager avec la communauté.
Mantosh Kumar
2
Je ne pense pas que ce soit une bonne motivation pour utiliser l'automobile. Activez simplement l'indicateur d'avertissement de votre compilateur pour l'utilisation de variables non initialisées et adressez-vous à tous les avertissements. Cela ne veut pas dire que vous ne devriez pas utiliser auto- mais vous n'en avez pas besoin pour éviter ce problème.
einpoklum
2

Un danger que j'ai noté concerne les références. par exemple

MyBigObject& ref_to_big_object= big_object;
auto another_ref = ref_to_big_object; // ?

Le problème est que another_ref n'est pas réellement une référence dans ce cas, c'est MyBigObject au lieu de MyBigObject &. Vous finissez par copier un gros objet sans vous en rendre compte.

Si vous obtenez une référence directement à partir d'une méthode, vous pourriez ne pas penser à ce qu'elle est réellement.

auto another_ref = function_returning_ref_to_big_object();

vous auriez besoin de "auto &" ou "const auto &"

MyBigObject& ref_to_big_object= big_object;
auto& another_ref = ref_to_big_object;
const auto& yet_another_ref = function_returning_ref_to_big_object();
user2495422
la source
1

Utilisez autolà où il est logique qu'un type soit déduit. Si vous savez que quelque chose est un entier ou que vous savez que c'est une chaîne, utilisez simplement int / std :: string, etc. ou obscurcit le code.

C'est mon avis de toute façon.

LainIwakura
la source
4
"où cela a du sens ..." est la partie la plus délicate. Les programmeurs peuvent être tellement pris dans les détails du codage qu'ils perdent tout sens de ce qui fait sens pour les autres programmeurs, en particulier les futurs responsables.
DarenW
C'est vrai, même si je pense qu'il est assez facile de dire quand c'est ambigu. En cas de doute, utilisez un commentaire!
LainIwakura
1
Ne serait-il pas logique d'utiliser un type?
Mikhail
Certains développeurs diraient que le type doit toujours être déduit!
Arafangion
Utilisez un commentaire ...... ou utilisez simplement le type et aucun commentaire nécessaire?
user997112
1

autoLe mot clé ne peut être utilisé que pour une variable locale, pas pour des arguments ou des membres de classe / structure. Il est donc sûr et viable de les utiliser où vous le souhaitez. Je les utilise beaucoup. Le type est déduit au moment de la compilation, le débogueur affiche le type pendant le débogage, le sizeofsignale correctement, decltypeil donnerait le type correct - il n'y a pas de mal. Je ne compte pas autocomme surutilisé, jamais!

Ajay
la source
0

TL; DR: Voir la règle générale en bas.

La réponse acceptée suggère la règle empirique suivante:

Utilisation auto chaque fois qu'il est difficile de dire comment écrire le type à première vue, mais le type du côté droit d'une expression est évident.

Mais je dirais que c'est trop restrictif. Parfois, je ne me soucie pas des types, car la déclaration est suffisamment informative sans que je prenne la peine de prendre le temps de comprendre le type. Qu'est-ce que je veux dire par là? Prenons l'exemple qui est apparu dans certaines des réponses:

auto x = f();

Qu'est-ce qui en fait un exemple d'utilisation abusive auto? Est-ce mon ignorance du f()type de retour de? Eh bien, cela pourrait effectivement aider si je le savais, mais - ce n'est pas ma principale préoccupation. Ce qui est beaucoup plus problématique, c'est cela xet f()n'a pas beaucoup de sens. Si nous avions:

auto nugget = mine_gold();

au lieu de cela, alors je ne me soucie généralement pas de savoir si le type de retour de la fonction est évident ou non. En lisant la déclaration, je sais ce que je fais et j'en sais assez sur la sémantique de la valeur de retour pour ne pas ressentir le besoin de connaître également son type.

Donc ma réponse est: à utiliser autochaque fois que le compilateur le permet, à moins que:

  • Vous pensez que le nom de la variable et l'expression d'initialisation / affectation ne fournissent pas suffisamment d'informations sur ce que fait l'instruction.
  • Vous pensez que le nom de la variable ainsi que l'expression d'initialisation / affectation fournissent des informations "trompeuses" sur ce que le type devrait être - c'est-à-dire, si vous deviez deviner ce qui vient au lieu de l'automobile, vous seriez en mesure de faire une supposition - et ce serait mal, et cette fausse supposition a des répercussions plus tard dans le code.
  • Vous souhaitez forcer un type différent (par exemple une référence).

Et aussi:

  • Préférez donner un nom significatif (qui ne contient pas le nom du type bien sûr) avant de le remplacer autopar le type concret.
einpoklum
la source
-3

Une de mes amères expériences avec autoson utilisation avec des expressions lambda :

auto i = []() { return 0; };
cout<<"i = "<<i<<endl; // output: 1 !!!

En fait, ici iest résolu de fonctionner le pointeur de int(*)(). C'est juste un simple cout, mais imaginez quel type d'erreurs de compilation / d'exécution incorrectes il peut provoquer lorsqu'il est utilisé avec template.

Vous devez éviter auto avec de telles expressions et mettre un returntype approprié (ou contrôlé decltype())

L'utilisation correcte pour l'exemple ci-dessus serait,

auto i = []() { return 0; }(); // and now i contains the result of calling the lambda  
iammilind
la source
7
Vous avez fait un travail terrible pour expliquer ce que cela a à voir avec l'automobile. Vous avez créé une fonction, puis l'imprimez ... D'accord?
Dennis Zickefoose
5
@iammilind: et qu'est-ce que cela a à voir avec l'automobile?
R. Martinho Fernandes
7
Je trouve très improbable que l'on veuille mettre ()à la fin. Les lambdas sont là pour agir comme des fonctions et c'est de là que vient la conversion du pointeur de fonction. Si vous voulez l'appeler tout de suite, pourquoi utiliser un lambda? auto i = 0;fonctionne plutôt bien.
R. Martinho Fernandes
4
Pouvez-vous au moins décrire un scénario où auto x = []() { /* .... whatever goes in here ... */ }()c'est mieux que auto x = /* .... whatever goes in here ... */;, c'est-à-dire la même chose, sans le lambda? Je trouve cela plutôt inutile, pour la même raison auto x = 42 + y - 42est inutile.
R. Martinho Fernandes
6
-1 ce n'est pas la faute de l'automobile. Le type d'un lambda ne peut pas être orthographié, donc auto est requis , si vous oubliez d' appeler la fonction, c'est votre propre surveillance! Vous pouvez placer un pointeur de fonction non appelé dans un printf C tout aussi au hasard.
pulvérisation le