Sélection générique (C11)
Utilisez le mot clé _Generic
pour écrire du code qui sélectionne une expression au moment de la compilation en fonction du type de l’argument. Il est similaire à la surcharge en C++ où le type de l’argument sélectionne la fonction à appeler. Dans ce cas, le type de l’argument sélectionne l’expression à évaluer.
Par exemple, l’expression _Generic(42, int: "integer", char: "character", default: "unknown");
évalue le type de 42
et recherche le type correspondant, int
, dans la liste. Il le trouve et retourne "integer"
.
Syntaxe
generic-selection
:
_Generic
( assignment-expression
, assoc-list
)
assoc-list
:
association
assoc-list
, association
association
:
type-name
: assignment-expression
default
: assignment-expression
La première assignment-expression
est appelée expression de contrôle. Le type de l’expression de contrôle est déterminé au moment de la compilation et mis en correspondance avec la assoc-list
pour trouver l’expression à évaluer et à retourner. L’expression de contrôle n’est pas évaluée. Par exemple, _Generic(intFunc(), int: "integer", default: "error");
n’entraîne pas d’appel à intFunc
au moment de l’exécution.
Lorsque le type de l’expression de contrôle est déterminé, const
, volatile
et restrict
sont supprimés avant la mise en correspondance avec assoc-list
.
Les entrées de la assoc-list
qui ne sont pas choisies ne sont pas évaluées.
Contraintes
- La
assoc-list
ne peut pas spécifier le même type plusieurs fois. - La
assoc-list
ne peut pas spécifier des types compatibles entre eux, tels qu’une énumération et le type sous-jacent de celle-ci. - Si une sélection générique n’a pas de valeur par défaut, l’expression de contrôle ne doit avoir qu’un seul nom de type compatible dans la liste d’associations génériques.
Exemple
Une façon d’utiliser _Generic
consiste à l’utiliser dans une macro. Le fichier d’en-tête <tgmath.h> utilise _Generic
pour appeler la fonction mathématique appropriée en fonction du type d’argument. Par exemple, la macro pour cos
mappe un appel avec une valeur flottante à cosf
, et un appel avec un double complexe à ccos
.
L’exemple suivant montre comment écrire une macro qui identifie le type de l’argument que vous lui transmettez. Elle produit "unknown"
si aucune entrée dans la assoc-list
ne correspond à l’expression de contrôle :
// Compile with /std:c11
#include <stdio.h>
/* Get a type name string for the argument x */
#define TYPE_NAME(X) _Generic((X), \
int: "int", \
char: "char", \
double: "double", \
default: "unknown")
int main()
{
printf("Type name: %s\n", TYPE_NAME(42.42));
// The following would result in a compile error because
// 42.4 is a double, doesn't match anything in the list,
// and there is no default.
// _Generic(42.4, int: "integer", char: "character"));
}
/* Output:
Type name: double
*/
Spécifications
Compilez avec /std:c11
.
SDK Windows 10.0.20348.0 (version 2104) ou ultérieure. Pour télécharger le Kit de développement logiciel (SDK) le plus récent, consultez SDK Windows. Pour obtenir des instructions sur l’installation et l’utilisation du Kit de développement logiciel (SDK) pour le développement en C11 et C17, consultez Installer la prise en charge de C11 et C17 dans Visual Studio.
Voir aussi
/std
(Spécifier la version du standard du langage)
Mathématiques de type générique