Share via


Selección genérica (C11)

Use la palabra clave _Generic para escribir código que seleccione una expresión en tiempo de compilación según el tipo del argumento. Este funcionamiento es similar a la sobrecarga en C++, en la que el tipo de argumento selecciona a qué función llamar. En este caso, el tipo del argumento selecciona la expresión que se va a evaluar.

Por ejemplo, la expresión _Generic(42, int: "integer", char: "character", default: "unknown"); evalúa el tipo de 42 y busca el tipo coincidente, int, en la lista. Lo encuentra y devuelve "integer".

Sintaxis

generic-selection:
_Generic(assignment-expression, assoc-list)

assoc-list:
association
assoc-list, association

association:
type-name : assignment-expression
default : assignment-expression

A la primera assignment-expression se le llama expresión de control. El tipo de la expresión de control se determina en tiempo de compilación y se compara con la assoc-list para encontrar la expresión que se va a evaluar y devolver. La expresión de control no se evalúa. Por ejemplo, _Generic(intFunc(), int: "integer", default: "error"); no produce una llamada en tiempo de ejecución a intFunc.

Cuando se determina el tipo de la expresión de control, const, volatile y restrict se quitan antes de compararse con assoc-list.

No se evaluarán las entradas de la assoc-list que no se hayan elegido.

Restricciones

  • La assoc-list no puede especificar el mismo tipo más de una vez.
  • La assoc-list no puede especificar tipos compatibles entre sí, como una enumeración y el tipo subyacente de esa enumeración.
  • Si una selección genérica no tiene un valor predeterminado, la expresión de control solo debe tener un nombre de tipo compatible en la lista de asociaciones genérica.

Ejemplo

Una manera de usar _Generic se encuentra en una macro. El archivo de encabezado <tgmath.h> usa _Generic para llamar a la función matemática correcta según el tipo de argumento. Por ejemplo, la macro para cos asigna una llamada con un valor float a cosf, mientras se asigna una llamada con un valor complex double a ccos.

En el ejemplo siguiente se muestra cómo escribir una macro que identifique el tipo del argumento que le pase. Produce "unknown" si no coincide ninguna entrada de la assoc-list con la expresión de control:

// 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
*/

Requisitos

Compile con /std:c11.

Windows SDK 10.0.20348.0 (versión 2104) o posterior. Consulte Windows SDK para descargar el SDK más reciente. Para obtener instrucciones sobre cómo instalar y usar el SDK para el desarrollo con C11 y C17, vea Instalación de la compatibilidad con C11 y C17 en Visual Studio.

Vea también

/std (Especificar la versión estándar del lenguaje)
Matemáticas de tipo genérico