Bagikan melalui


Pilihan generik (C11)

Gunakan kata kunci _Generic untuk menulis kode yang memilih ekspresi pada waktu kompilasi berdasarkan jenis argumen. Ini mirip dengan kelebihan beban di C++ di mana jenis argumen memilih fungsi mana yang akan dipanggil. Dalam hal ini, jenis argumen memilih ekspresi mana yang akan dievaluasi.

Misalnya, ekspresi _Generic(42, int: "integer", char: "character", default: "unknown"); mengevaluasi jenis 42 dan mencari jenis yang cocok, int, dalam daftar. Ini menemukannya dan mengembalikan "integer".

Sintaks

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

assoc-list:
association
assoc-list, association

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

assignment-expression yang pertama disebut ekspresi pengontrol. Jenis ekspresi pengontrol ditentukan pada waktu kompilasi dan dicocokkan dengan assoc-list untuk menemukan ekspresi mana yang akan dievaluasi dan dikembalikan. Ekspresi pengontrol tidak dievaluasi. Misalnya, _Generic(intFunc(), int: "integer", default: "error"); tidak menghasilkan panggilan saat runtime ke intFunc.

Ketika jenis ekspresi pengontrol ditentukan, const, volatile, dan restrict dihapus sebelum dicocokkan dengan assoc-list.

Entri dalam assoc-list yang tidak dipilih tidak dievaluasi.

Batasan

  • assoc-list tidak dapat menentukan jenis yang sama lebih dari sekali.
  • assoc-list tidak dapat menentukan jenis yang kompatibel satu sama lain, seperti enumerasi dan jenis enumerasi yang mendasar.
  • Jika pilihan generik tidak memiliki default, ekspresi pengontrol hanya boleh memiliki satu nama jenis yang kompatibel dalam daftar asosiasi generik.

Contoh

Salah satu cara untuk menggunakan _Generic adalah dalam makro. File header <tgmath.h> menggunakan _Generic untuk memanggil fungsi matematika yang tepat tergantung pada jenis argumen. Misalnya, makro untuk cos memetakan panggilan dengan float ke cosf, sambil memetakan panggilan dengan ganda kompleks ke ccos.

Contoh berikut menunjukkan cara menulis makro yang mengidentifikasi tipe argumen yang Anda berikan padanya. Ini menghasilkan "unknown" jika tidak ada entri dalam yang assoc-list cocok dengan ekspresi pengontrol:

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

Persyaratan

Kompilasikan dengan /std:c11.

Windows SDK 10.0.20348.0 (versi 2104) atau yang lebih baru. Lihat Windows SDK untuk mengunduh SDK terbaru. Untuk instruksi menginstal dan menggunakan SDK untuk pengembangan C11 dan C17, lihat Menginstal dukungan C11 dan C17 di Visual Studio.

Lihat juga

/std (Tentukan versi standar bahasa)
Matematika generik jenis