Partilhar via


Seleção genérica (C11)

Use a palavra-chave para escrever código _Generic que seleciona uma expressão em tempo de compilação com base no tipo do argumento. É semelhante à sobrecarga em C++, onde o tipo do argumento seleciona qual função chamar. Nesse caso, o tipo de argumento seleciona qual expressão avaliar.

Por exemplo, a expressão _Generic(42, int: "integer", char: "character", default: "unknown"); avalia o tipo de e procura o tipo correspondente 42 , int, na lista. Encontra-o e devolve-o "integer".

Sintaxe

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

assoc-list:
association
assoc-list, association

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

A primeira assignment-expression é chamada de expressão controladora. O tipo da expressão de controle é determinado em tempo de compilação e comparado com o assoc-list para encontrar qual expressão avaliar e retornar. A expressão controladora não é avaliada. Por exemplo, _Generic(intFunc(), int: "integer", default: "error"); não resulta em uma chamada em tempo de execução para intFunc.

Quando o tipo da expressão de controle é determinado, const, volatilee restrict são removidos antes de corresponder a assoc-list.

As entradas que assoc-list não são escolhidas não são avaliadas.

Restrições

  • O assoc-list não pode especificar o mesmo tipo mais de uma vez.
  • O assoc-list não pode especificar tipos que são compatíveis entre si, como uma enumeração e o tipo subjacente dessa enumeração.
  • Se uma seleção genérica não tiver um padrão, a expressão de controle deverá ter apenas um nome de tipo compatível na lista de associação genérica.

Exemplo

Uma maneira de usar _Generic é em uma macro. O <arquivo de cabeçalho tgmath.h> usa _Generic para chamar a função matemática correta, dependendo do tipo de argumento. Por exemplo, a macro para cos mapeia uma chamada com um float para cosf, enquanto mapeia uma chamada com um duplo complexo para ccos.

O exemplo a seguir mostra como escrever uma macro que identifica o tipo do argumento que você passa para ela. Ele produz "unknown" se nenhuma entrada na assoc-list corresponde a expressão de controle:

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

Requerimentos

Compilar com /std:c11.

Windows SDK 10.0.20348.0 (versão 2104) ou posterior. Consulte SDK do Windows para baixar o SDK mais recente. Para obter instruções sobre como instalar e usar o SDK para desenvolvimento C11 e C17, consulte Instalar suporte a C11 e C17 no Visual Studio.

Ver também

/std (Especificar a versão normalizada da língua)
Matemática genérica de tipos