Skip to content

Commit 6ef9297

Browse files
committed
C++ Auto : Multiples déclarations
1 parent 5580a70 commit 6ef9297

1 file changed

Lines changed: 48 additions & 4 deletions

File tree

_articles/c++_auto.md

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,9 @@ L'usage explicite de ``auto*`` permet de signaler de manière claire que vous tr
9696
Deux termes sont parfois utilisées: [**auto to track**](#auto-to-track) et [**auto to stick**](#auto-to-stick).<br>
9797
Il est bon de les aborder pour **comprendre l'intérêt** de cette nouvelle écriture.
9898

99+
> **auto to track** et **auto to stick** ne sont que des terminologies **informelles** décrivant l'intention du développeur.<br>
100+
> Les deux usages reposent sur exactement **les mêmes règles de déduction**. Il ne s'agit pas de mécanismes fondamentalement différents.
101+
99102
### auto to track
100103

101104
Lorsque le mot clef ``auto`` sert à déduire le type de la variable **à partir du type de retour d'une fonction**, on appelle cela "**auto to track**".
@@ -119,7 +122,7 @@ std::basic_string<CharT,Traits,Alloc> std::basic_string<char>::operator+(const s
119122
{% endhighlight %}
120123
Et du type de retour de cet opérateur, il en déduit le type de notre variable ``string2``.
121124

122-
#### auto to track complique la lecture du code ?
125+
#### auto to track complique la lecture du code?
123126

124127
Les développeurs réticents à utiliser **auto to track** soutiennent que de **ne pas écrire explicitement le type des variables ajoute en charge mentale** pour les développeurs. Forçant à **faire l'effort d'aller vérifier les types de retour des fonctions** pour connaitre le type des variables typées avec ``auto``.
125128

@@ -194,7 +197,7 @@ auto data = std::string{std::data(string)};
194197

195198
> Notez qu'ici, le type de ``data`` n'est plus compliqué à retrouver puisqu'il est écrit directement à droite du signe égal.
196199
197-
> Attention, comme dit [plus haut](/#auto-to-track-complique-la-lecture-du-code-), il est important de **vérifier les types de retour des fonctions** pour prévenir toute conversion implicite.<br>
200+
> Attention, comme dit [plus haut](#auto-to-track-complique-la-lecture-du-code), il est important de **vérifier les types de retour des fonctions** pour prévenir toute conversion implicite.<br>
198201
> Et surtout d'**expliciter toute conversion souhaitée**.
199202
{: .block-warning }
200203

@@ -303,7 +306,8 @@ int main()
303306

304307
### auto to stick
305308

306-
Lorsque le mot clef ``auto`` sert à **affecter directement une valeur** à une variable, on appelle ça "**auto to stick**".
309+
Lorsque le mot clef ``auto`` sert à **affecter directement une valeur** à une variable, on appelle ça "**auto to stick**".<br>
310+
On reconnait cette écriture par la présence directe d'un **literal** ou un **constructeur** à droite du signe égal.
307311

308312
Exemples:
309313
{% highlight cpp %}
@@ -339,7 +343,7 @@ auto string3 = std::string{"Hello"}; // Pourquoi s'encombrer d'un "auto" en plus
339343
Au delà de son écriture légèrement plus verbeuse, **auto to stick** présente de nombreux avantages.<br>
340344
Commençons par l'uniformisation qu'elle propose:
341345

342-
#### Oublier une définition
346+
#### Oublier une initialisation
343347

344348
{% wip %}
345349

@@ -404,6 +408,40 @@ int b = 3.14; // double vers int: Erreur
404408
{% endhighlight %}
405409
{% endrow %}
406410

411+
### Multiples déclarations
412+
413+
Lorsqu'on écrit:
414+
{% highlight cpp %}
415+
int number1 = 1, number2 = 2; // number1 et number2 sont de type int
416+
{% endhighlight %}
417+
On déclare simultanément deux variables de type ``int``, comme si l'on avait fait deux déclarations séparées:
418+
{% highlight cpp %}
419+
int number1 = 1;
420+
int number2 = 2;
421+
{% endhighlight %}
422+
423+
De la même manière avec ``auto``, le compilateur doit déduire le même type identique à toutes les variables d'une déclaration multiple.
424+
{% highlight cpp %}
425+
auto number1 = 1, number2 = 2; // number1 et number2 sont de type int
426+
auto number = 1, string = "Hello World!"; // error: 'auto' deduced as 'int' in declaration of 'number' and deduced as 'const char *' in declaration of 'string'
427+
{% endhighlight %}
428+
429+
Et contrairement au [cas des ternaires](#common-type-deduction), ``auto`` ne déduit pas un [type commun](#common-type-deduction) dans les déclarations multiples.
430+
{% highlight cpp %}
431+
auto number3 = 1, number4 = 1.2; // error: 'auto' deduced as 'int' in declaration of 'number3' and deduced as 'double' in declaration of 'number4'
432+
{% endhighlight %}
433+
434+
Les propriétés cvref étant dissociées de ``auto``, il est possible d'avoir dans une même déclaration multiple plusieurs types qui ne varient que par leurs propriétés cvref.
435+
{% highlight cpp highlight_lines="2" %}
436+
auto number = 1;
437+
auto value = number, &reference = number, *pointer = &number;
438+
{% endhighlight %}
439+
440+
Les variables déclarées plus tôt dans une même déclaration multiple sont immédiatement utilisables.
441+
{% highlight cpp %}
442+
auto lhs = 21, rhs = 2, result = lhs * rhs;
443+
{% endhighlight %}
444+
407445
## Trailing return type (depuis C++11)
408446

409447
En C++, le type de retour des fonctions est écrit au début de leur définition/déclaration:
@@ -1187,6 +1225,10 @@ struct HeterogenousValueList {};
11871225
using MyList = HeterogenousValueList<42, 'X', 13u>;
11881226
{% endhighlight %}
11891227

1228+
### ``auto`` in template parameters (depuis C++20)
1229+
1230+
{% wip %}
1231+
11901232
## AA (Always Auto) (depuis C++17)
11911233

11921234
En C++17, le langage garanti la [copy elision](/articles/c++/copy_elision), faisant disparaitre les surcoûts que nous avons vu [à la fin de la partie sur "Amost Always Auto"](#aaa-almost-always-auto-avant-c17), rendant l'utilisation de ``auto`` possible même sur des types qui ne sont ni copyables, ni movables.
@@ -1264,6 +1306,8 @@ function(auto(expr));
12641306
function(auto{expr});
12651307
{% endhighlight %}
12661308

1309+
{% wip %}
1310+
12671311
## Structured binding pack (depuis C++26)
12681312

12691313
Dans la continuité des [structured binding declaration](#structured-binding-declaration-depuis-c17), le C++26 ajoute la possibilité de d'extraire des éléments d'un [pack](/articles/c++/templates#pack) ([proposal](https://wg21.link/P1061R10), [approval](https://wg21.link/P1061R9/status)).

0 commit comments

Comments
 (0)