Udostępnij za pośrednictwem


Wybór ogólny (C11)

Użyj słowa kluczowego _Generic , aby napisać kod, który wybiera wyrażenie w czasie kompilacji na podstawie typu argumentu. Jest on podobny do przeciążenia w języku C++, w którym typ argumentu wybiera funkcję do wywołania. W tym przypadku typ argumentu wybiera wyrażenie do obliczenia.

Na przykład wyrażenie _Generic(42, int: "integer", char: "character", default: "unknown"); oblicza typ 42 i wyszukuje pasujący typ , intna liście. Znajduje go i zwraca wartość "integer".

Składnia

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

assoc-list:
association
assoc-list, association

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

Pierwszy assignment-expression jest nazywany wyrażeniem sterującym. Typ wyrażenia sterującego jest określany w czasie kompilacji i dopasowany do assoc-list elementu w celu znalezienia wyrażenia, które ma być obliczane i zwracane. Wyrażenie sterujące nie jest oceniane. Na przykład _Generic(intFunc(), int: "integer", default: "error"); nie powoduje wywołania w czasie wykonywania polecenia .intFunc

Gdy typ wyrażenia sterującego zostanie określony, const, volatilei restrict zostaną usunięte przed dopasowaniem względem assoc-listelementu .

Wpisy w elemecie assoc-list , które nie są wybrane, nie są oceniane.

Ograniczenia

  • Nie assoc-list można określić tego samego typu więcej niż raz.
  • Nie assoc-list można określić typów, które są ze sobą zgodne, takie jak wyliczenie i podstawowy typ tego wyliczenia.
  • Jeśli wybór ogólny nie ma wartości domyślnej, wyrażenie sterujące musi mieć tylko jedną zgodną nazwę typu na liście skojarzeń ogólnych.

Przykład

Jednym ze sposobów użycia _Generic jest makro. Plik nagłówkowy <tgmath.h> używa _Generic metody do wywoływania właściwej funkcji matematycznej w zależności od typu argumentu. Na przykład makro mapuje cos wywołanie z zmiennoprzecinkowym na cosf, mapując wywołanie ze złożonym podwójnym ccosna .

W poniższym przykładzie pokazano, jak napisać makro, które identyfikuje typ przekazanego do niego argumentu. "unknown" Tworzy, jeśli w wyrażeniu sterującym assoc-list nie ma wpisu zgodnego z wyrażeniem sterującym:

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

Wymagania

Skompiluj za pomocą polecenia /std:c11.

Windows SDK 10.0.20348.0 (wersja 2104) lub nowsza. Zobacz Zestaw Windows SDK , aby pobrać najnowszy zestaw SDK. Aby uzyskać instrukcje dotyczące instalowania i używania zestawu SDK dla programowania C11 i C17, zobacz Instalowanie obsługi C11 i C17 w programie Visual Studio.

Zobacz też

/std (Określ wersję standardową języka)
Matematyka ogólna typu