You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
> Le langage C a effectué le même changement au niveau de [son mot clef ``auto``](https://en.cppreference.com/w/c/language/auto) en [C23](https://en.cppreference.com/w/c/23) en lui donnant la même fonction qu'en C++11 pour faire de l'**inférence de types** ([proposal](https://open-std.org/JTC1/SC22/WG14/www/docs/n3007.htm)).
77
+
75
78
### Pointeurs et propriétés cvref
76
79
77
80
Par défaut, ``auto`` ne récupère pas les propriétés **cvref** (``const``/``volatile``/``reference``) de la valeur qui lui est assignée.
@@ -639,7 +642,7 @@ template<class Lhs, class Rhs>
639
642
auto sum(Lhs lhs, Rhs rhs) -> decltype(lhs + rhs)
640
643
{
641
644
return lhs + rhs;
642
-
};
645
+
}
643
646
{% endhighlight %}
644
647
645
648
> Si vous n'êtes pas familiers avec les templates, passez faire un tour [ici](/articles/c++/templates).
@@ -652,7 +655,7 @@ template<class Lhs, class Rhs>
652
655
decltype(lhs + rhs) sum(Lhs lhs, Rhs rhs)
653
656
{
654
657
return lhs + rhs;
655
-
};
658
+
}
656
659
{% endhighlight %}
657
660
658
661
> \<source\>:5:10: **error**: 'lhs' was not declared in this scope;<br>
@@ -749,7 +752,7 @@ template<class Lhs, class Rhs>
749
752
auto sum(Lhs lhs, Rhs rhs)
750
753
{
751
754
return lhs + rhs;
752
-
};
755
+
}
753
756
{% endhighlight %}
754
757
755
758
Cependant, ce n'est pas une écriture que vous verrez souvent car elle **comporte des risques** et qu'elle **ne couvre pas toutes les situations**.
@@ -772,7 +775,7 @@ template<class Lhs, class Rhs>
772
775
auto sum(Lhs lhs, Rhs rhs)
773
776
{
774
777
return lhs + rhs;
775
-
};
778
+
}
776
779
{% endhighlight %}
777
780
778
781
Il arrive que la fonction contienne plusieurs ``return``.
@@ -786,7 +789,7 @@ auto getText(int value)
786
789
return "La valeur est positive"; // const char*
787
790
else
788
791
return std::string_view{"La valeur est négative"}; // std::string_view
789
-
};
792
+
}
790
793
{% endhighlight %}
791
794
792
795
Ceci provoque une erreur de compilation, bien qu'un [type commun](/articles/c++/type_traits#type_commun) existe (``std::string_view``)
@@ -802,7 +805,7 @@ auto getText(int value) -> std::string_view
802
805
return "La valeur est positive"; // const char*
803
806
else
804
807
return std::string_view{"La valeur est négative"}; // std::string_view
805
-
};
808
+
}
806
809
{% endhighlight %}
807
810
808
811
Le compilateur tente maintenant de construire un ``std::string_view`` à partir du ``const char*`` retourné. Ce qui est fait via un appel implicite à un constructeur de ``std::string_view``.
@@ -817,7 +820,7 @@ template<class Lhs, class Rhs>
817
820
auto sum(Lhs lhs, Rhs rhs) -> auto
818
821
{
819
822
return lhs + rhs;
820
-
};
823
+
}
821
824
{% endhighlight %}
822
825
823
826
Ici, il n'y a pas de redondance du mot clef ``auto``.<br>
@@ -841,7 +844,7 @@ template<class Function>
841
844
auto call(Function function) -> decltype(auto)
842
845
{
843
846
return function();
844
-
};
847
+
}
845
848
846
849
// call(foo) retourne un int
847
850
// call(bar) retourne un int&
@@ -853,7 +856,7 @@ auto main() -> int
853
856
{
854
857
decltype(auto) result = call(bar);
855
858
return result;
856
-
};
859
+
}
857
860
{% endhighlight %}
858
861
859
862
Avec cette initialisation de variable, il est possible de faire ceci:
Les classes/structures ayant **toutes leurs variables membres publiques** sont déstructurables avec une *structured binding declaration*:
947
950
948
951
{% highlight cpp linenos highlight_lines="10" %}
949
-
struct Position2d
952
+
struct Point2d
950
953
{
951
954
int x;
952
955
int y;
953
956
};
954
957
955
958
auto main() -> int
956
959
{
957
-
auto position = Position2d{10, 15}; // Construction d'un Position2d avec x vallant 10 et y vallant 15
958
-
auto [x, y] = position; // Extraction des variables membre de Position2d
960
+
auto position = Point2d{10, 15}; // Construction d'un Point2d avec x vallant 10 et y vallant 15
961
+
auto [x, y] = position; // Extraction des variables membre de Point2d
959
962
std::println("{} {}", x, y); // Affiche: "10 15"
960
963
}
961
964
{% endhighlight %}
@@ -964,15 +967,15 @@ La déstructuration doit **respecter l'ordre des paramètres**.<br>
964
967
**Leur nom n'a pas d'importance**, il peut être changé. Par exemple: ``auto [foo, bar] = position;``
965
968
966
969
{% highlight cpp linenos highlight_lines="10" %}
967
-
struct Position2d
970
+
struct Point2d
968
971
{
969
972
int x;
970
973
int y;
971
974
};
972
975
973
976
auto main() -> int
974
977
{
975
-
auto position = Position2d{10, 15};
978
+
auto position = Point2d{10, 15};
976
979
auto [a, b] = position;
977
980
std::println("{} {}", a, b); // Affiche: "10 15" malgré l'utilisation de noms de variables différents
978
981
}
@@ -982,10 +985,10 @@ auto main() -> int
982
985
Ceci est également valable pour [chaque type cité ci-dessous](#c-like-array)
983
986
984
987
{% highlight cpp %}
985
-
auto position = Position2d{10, 15};
986
-
auto [x] = position; // error: type 'Position2d' decomposes into 2 elements, but only 1 name was provided
988
+
auto position = Point2d{10, 15};
989
+
auto [x] = position; // error: type 'Point2d' decomposes into 2 elements, but only 1 name was provided
987
990
auto [x, y] = position; // Ok
988
-
auto [x, y, z] = position; // error: type 'Position2d' decomposes into 2 elements, but 3 names were provided
991
+
auto [x, y, z] = position; // error: type 'Point2d' decomposes into 2 elements, but 3 names were provided
989
992
{% endhighlight %}
990
993
991
994
### Propriétés cvref
@@ -1416,7 +1419,7 @@ template<class Lhs, class Rhs>
1416
1419
auto sum(Lhs lhs, Rhs rhs) -> auto
1417
1420
{
1418
1421
return lhs + rhs;
1419
-
};
1422
+
}
1420
1423
{% endhighlight %}
1421
1424
1422
1425
Depuis C++20, il est possible d'utiliser ``auto`` comme syntaxe alternative aux templates, améliorant grandement leur lisibilité:
@@ -1425,7 +1428,7 @@ Depuis C++20, il est possible d'utiliser ``auto`` comme syntaxe alternative aux
1425
1428
auto sum(auto lhs, auto rhs) -> auto
1426
1429
{
1427
1430
return lhs + rhs;
1428
-
};
1431
+
}
1429
1432
{% endhighlight %}
1430
1433
1431
1434
> Attention, derrière ses airs de [placeholder type specifiers](#placeholder-type-specifiers-depuis-c11), il s'agit ici bien de **types templatés**.<br>
@@ -1444,7 +1447,7 @@ Comme avec les templates, il est toujours possible de faire des *variadic templa
1444
1447
auto sum(auto... types) -> auto
1445
1448
{
1446
1449
return (types + ...);
1447
-
};
1450
+
}
1448
1451
{% endhighlight %}
1449
1452
1450
1453
Lorsque templates et paramètres ``auto`` sont combinés, cela équivaut à avoir les types des paramètres ``auto`` après les templates:
@@ -1494,7 +1497,7 @@ A première vue on pourrait penser que ça ne répond à aucun besoin réel.<br>
1494
1497
Mais regardons [la motivation](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p0849r8.html#Motivation) derrière cet ajout:
1495
1498
1496
1499
Prenons le code suivant, dans lequel on veut supprimer toute occurrence de la première valeur (``"A"``):
Elle prend une **référence** sur un ``std::vector`` ainsi qu'une **référence constante** sur l'élément à rechercher et **à supprimer** dans le conteneur.
1523
1526
1524
1527
[La documentation](https://en.cppreference.com/w/cpp/container/vector/erase2) nous dit que la fonction [``std::erase``](https://en.cppreference.com/w/cpp/container/vector/erase2) supprime chaque élément du conteneur ``c`` égal à l'argument ``value`` de la manière suivante:
0 commit comments