'auto' comme espace réservé d'argument de modèle pour un paramètre de fonction

22

C ++ 20 permet d'utiliser le autotype de paramètre de fonction.

Cela permet-il également d'utiliser autocomme espace réservé d'argument de modèle (pas similaire, mais dans l'esprit du modèle C ++ 17 <auto> d'une certaine manière) pour le type de paramètre de fonction?

Donc le code suivant, pré C ++ 20:

template<typename First, typename Second>
void printPair(const std::pair<First, Second>& p) {
    std::cout << p.first << ", " << p.second;
}

Pourrait être écrit comme:

void printPair(const std::pair<auto, auto>& p) {
    std::cout << p.first << ", " << p.second;
}

Il compile et fonctionne bien avec l'implémentation expérimentale de GCC pour les concepts.

Est-ce une syntaxe légitime avec C ++ 20?

Amir Kirsh
la source
D'après ce que j'ai entendu, sans contrainte auto se traduit directement en modèle typename XYZ, ce qui impliquerait fortement que c'est la syntaxe légitime. Neat .
Fureeish
2
Notez que Clang n'est pas d'accord et que Clang et GCC ont le même désaccord quant à savoir si autoest autorisé à entrer [](const std::pair<auto, auto>& p){}(que ce soit avec -std=c++2aou -std=c++17).
noyer
Merci @DavisHerring - J'ai corrigé le libellé
Amir Kirsh

Réponses:

17

Cette syntaxe est valide dans la spécification technique des concepts C ++, mais pas dans C ++ 20. Dans les concepts C ++ 20, auton'est autorisé qu'au niveau supérieur dans un type de paramètre de fonction. La règle pertinente est [dcl.spec.auto] paragraphe 2 :

Un spécificateur de type d'espace réservé de la forme type-constraint [opt] autopeut être utilisé comme spécificateur de déclinaison de la spécification de déclinaison-seq d'une déclaration de paramètre d' une déclaration de fonction ou d'une expression lambda et, si ce n'est pas le auto spécificateur de type introduisant un type de retour de fin (voir ci-dessous), est un espace réservé de type de paramètre générique de la déclaration de fonction ou expression-lambda. [Remarque: La présence d'un espace réservé de type de paramètre générique signifie que la fonction est un modèle de fonction abrégé (9.3.3.5 [dcl.fct]) ou que le lambda est un lambda générique (7.5.5 [expr.prim.lambda]). —Fin note]

(Si vous vérifiez le libellé du projet de travail le plus récent au moment de la rédaction, vous trouverez une règle quelque peu différente. La règle ci-dessus a été modifiée par le problème principal 2447 , qui a été voté dans le projet final C ++ 20 à Prague réunion du comité il y a une semaine.)

Les spécificateurs de déclins dans un paramètre de fonction sont la séquence initiale de mots clés et de noms de type au début de la déclaration de paramètre. La règle ci-dessus permet autoau niveau supérieur:

void f(auto x);

... mais uniquement en tant que spécificateur décl . auton'est pas autorisé lorsqu'il est imbriqué dans un spécificateur décl :

void f(std::vector<auto> x);

... et n'est également pas autorisé ailleurs dans le type de paramètre:

void f(void (*p)(auto));
Richard Smith
la source
Wow, je ne savais pas ça! Le lien CWG donne actuellement 404, pouvez-vous donc expliquer brièvement la raison de cette restriction?
LF
C'est tout à fait décevant.
Fureeish
1
Désolé, le problème CWG et son changement de formulation ne sont pas encore visibles publiquement. La règle en question a été introduite par open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1141r2.html et l'intention / la justification devait être cohérente avec ce que nous autorisions déjà pour les lambdas génériques.
Richard Smith
4
@LF: Le problème CWG n'est pas vraiment pertinent de toute façon: il a corrigé une erreur de formulation qui impliquait que certaines utilisations de autopour un type de retour de fin comptaient comme ce type d' autoutilisation.
Davis Herring