Dans C ++ 20, nous sommes maintenant en mesure de contraindre le mot-clé Auto
pour être uniquement de type spécifique. Donc, si j'avais un code qui ressemblait à ce qui suit sans aucune contrainte:
std::integral auto something(){ return 0; } int main(){ const auto x = something(); return x; }
La variable x
ici est déduite comme un int
. Cependant, avec l'introduction de C ++ 20, nous pouvons maintenant contraindre que le auto
soit un certain type comme ceci:
auto something(){ return 1; } int main(){ const auto x = something(); return x; }
Cela vainc le but de auto
ici? Si j'ai vraiment besoin d'un std :: intégral
type de données, je ne pourrais pas simplement omettre complètement le auto
? Suis-je en train de mal comprendre complètement l'utilisation de auto
?
3 Réponses :
Une contrainte sur le type déduit par exemple. Un concept comme std :: intégral contrainte le type déduit comme un type intégral, tels que Si j'ai vraiment besoin d'un type de données En principe, je suppose que vous pourriez, mais cela aurait le moindre conduite à des difficultés d'analyse. par exemple. Dans une déclaration comme est alors que dans la syntaxe actuelle , nous avons et il ne fait aucun doute que auto
ne signifie pas qu'il doit être un type spécifique , cela signifie qu'il doit être l'un d'un set de types qui satisfont la contrainte. Notez qu'une contrainte et un type ne sont pas la même chose, et ils ne sont pas interchangeables. int
ou long
, mais pas float
, ou std :: string
. std :: intégral
, je ne pourrais pas simplement omettre le auto
complètement? foo auto f = // ...
foo
un type, ou une contrainte sur le type? foo f = // ...
foo
est une contrainte sur le type de f
.
Merci, cela clarifie les choses. D'après ce que je comprends, cela a-t-il été introduit afin que le programmeur sait en quelque sorte à quoi s'attendre d'une fonction qui utilise l'auto comme type de retour? Cela rendra sûrement le code moins sujet aux insectes et plus facile à déboguer, est-ce correct?
@MaHEEPPARTAPSIGH Oui, les concepts permettent au programmeur de rendre l'intention beaucoup plus claire, ce qui est toujours agréable. Il y a un tas d'avantages supplémentaires, par exemple Les modèles de fonction qui sont instanciés incorrectement peuvent être capturés plus facilement avec des concepts; Sinon, il faudrait que la définition échoue, ce qui est désagréable (produit de mauvais messages d'erreur, par exemple)
Auto
m'a fait des surprises assez intéressantes au fil des ans. Souvent, cela signifie que je n'ai pas obtenu quelque chose de bien ailleurs et que les diagnostics supplémentaires que je pourrais obtenir avec une contrainte peuvent assister à une erreur d'exécution autrement délicate ou à plusieurs pages de notes de résolution de modèle / de surcharge Nigh-Inscrit.
IIRC, les versions antérieures de la proposition / implémentation "Concepts Lite" n'avaient pas le auto
dans la syntaxe. Je crois que c'est principalement pour la clarté et les concepts sont déjà leur propre catégorie syntaxique, similaire aux types.
Mec, j'ai pensé à plusieurs reprises que ce serait génial si ma langue de choix ces jours-ci (TypeScript) avait cette fonctionnalité. Ravi de voir que je ne suis pas seul là-dedans!
En pratique, cela remplit à peu près le même objectif que d'inclure un static_assert
vérifier si le type de Auto F
est valide par std :: intégral
Les règles, comme cela se ferait généralement dans les versions de langue antérieure. Il est similaire à la contrainte de paramètres de modèle à une interface spécifique dans, par exemple, Java ou C #.
Si j'ai vraiment besoin d'un type de données std :: intégral
, je ne pourrais pas simplement omettre complètement l'auto?
Non, parce que std :: intégral
n'est pas un type, c'est un concept , une contrainte sur les types (ou si vous Will, un ensemble de types plutôt qu'un seul type).
Cela ne bat-il pas le but de l'auto ici?
Le but d'origine de Auto
dans C ++ 11 est le compilateur: quel que soit le type que vous déduisez .
avec C ++ 20, Auto
a un cas d'utilisation élargi - avec un concept, une contrainte sur les types. auto
Still indique au compilateur: quel que soit le type que vous déduisez - mais la déduction doit également respecter la contrainte.
Il est intéressant de noter que contraigne donne plus (ou élargi) cas d'utilisation. Mais je suis d'accord: la contrainte donne plus de puissance car elle donne plus de garanties . :-)
@Pabloh: similaire au principe de l'héritage dans la conception orientée objet. La classe «Sub» a potentiellement plus de fonctionnalités que le parent ou la classe «super».
RE Le but d'origine de l'auto est de dire au compilateur: quel que soit le type que vous déduisez. Le but d'origine de l'auto était de dire au compilateur qu'un objet avait un stockage automatique (par opposition à enregistrer ou
statique
ou extern
). Le mot-clé Auto
a été rarement utilisé car c'était la valeur par défaut des variables à la portée du bloc. Il n'y avait aucune raison d'utiliser l'auto parfois foo
lorsque quelqueype foo
signifiait la même chose. C'est ce qui a permis d'usurper le mot-clé Auto
dans C ++ 11 à d'autres fins.
@DavidHammen: Édité pour clarifier que nous parlons de C ++ 11-Auto, et non de l'utilisation antérieure du mot-clé qui n'est pas lié à cette question.
Un concept déplace souvent l'erreur plus tôt dans la compilation et rend le code un peu plus lisible (puisque le nom du concept est un indice pour le lecteur ce dont vous avez besoin d'un type).
reformulé:
Il est rare que vous utiliserez jamais une variable automatique d'une manière qu'il fonctionnera sur tous les types.Par exemple:
auto fn(std::integral auto x) { return x++; }
std :: intégral
n'est pas un type, c'est un concept. La deuxième version du code promet simplement que tout typequelque chose ()
renvoie, ce sera un type qui satisfait le conceptstd :: intégral
.L'objectif principal de cette syntaxe concerne les paramètres, où il est clairement utile; Les types de retour et les variables ordinaires ne sont qu'un bonus.