5 votes

Concept avec plusieurs arguments de modèle

J'essaie d'utiliser les concepts du C++20, pour commencer à me familiariser avec eux. Je me sens assez à l'aise avec les concepts simples, par exemple avec le concept standard movable Je peux écrire quelque chose comme ceci (dans tous les exemples, je suppose que je suis using namespace std et j'ai inclus <concepts> et tout autre en-tête nécessaire) :

template<movable T>
int foo (T obj);

Et assurez-vous que lorsque cette fonction est appelée, l'objet transmis obj peuvent être déplacés. Je peux l'écrire même sous une forme plus longue :

template<typename T>
requires movable<T>
int foo (T obj);

Et le résultat serait le même (je pense).

Mais examinons maintenant un autre concept tel que same_as . same_as prend en paramètre 2 modèles (les 2 types à comparer), ce qui me permet d'écrire :

template<typename T>
requires same_as<T, string>
int bar (T obj);

Et maintenant, T est string . Mais comment puis-je l'écrire sous une forme plus courte ? J'ai essayé, et je peux l'écrire (comme je m'y attendais intuitivement) :

template<same_as<string> T>
int bar (T obj);

Mais quelle est la règle formelle qui sous-tend ce formulaire ?

Est-ce que le nom ( T ) du paramètre du modèle de fonction, saisi comme premier argument du modèle de concept ? Ou peut-être en dernier ? Je ne sais pas, il y a très peu d'informations à ce sujet. Je veux dire que dans cet exemple, ce n'est pas pertinent, parce que same_as<A, B> est sémantiquement équivalent a same_as<B, A> mais il y a des cas où l'ordre a de l'importance.


Je sais qu'il existe des questions aux titres similaires, telles que celui-ci mais il s'agit d'une question différente.

Voici les ressources auprès desquelles j'ai essayé d'obtenir des informations, mais sans succès : cppRéférence , cppModernes , open-std (j'ai parcouru les années 2018, 2019 et 2020) y ce poste .

5voto

Barry Points 45207

Mais quelle est la règle formelle qui sous-tend ce formulaire ?

La règle (que vous avez correctement devinée) est décrite dans le document suivant [temp.param]/4 :

A contrainte de type Q qui désigne un concept C peut être utilisé pour contraindre un type déterminé par le contexte ou un paquet de paramètres de type de modèle T avec un expression de la contrainte E d Si Q est de la forme C<A1, , An> , alors laissez E sea C<T, A1, , An> . Dans le cas contraire, laissez E sea C<T> . Si T n'est pas un paquet, alors E es E sinon E es (E && ...) . Cette expression de la contrainte E est appelé contrainte immédiatement déclarée de Q para T . Le concept désigné par un contrainte de type doit être un concept de type ([temp.concept]).

Avec des exemples dans le paragraphe suivant :

A type-paramètre qui commence par un contrainte de type introduit la contrainte immédiatement déclarée de la contrainte de type f [Exemple :

template<typename T> concept C1 = true;
template<typename... Ts> concept C2 = true;
template<typename T, typename U> concept C3 = true;

template<C1 T> struct s1;               // associates C1<T>
template<C1... T> struct s2;            // associates (C1<T> && ...)
template<C2... T> struct s3;            // associates (C2<T> && ...)
template<C3<int> T> struct s4;          // associates C3<T, int>
template<C3<int>... T> struct s5;       // associates (C3<T, int> && ...)

- ]

Vous pouvez également penser à template <C T> comme étant une abréviation de template <C<> T> puis le paramètre de type T s'insère toujours dans le premier argument du concept.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X