一般選取 (C11)
使用 _Generic
關鍵字來撰寫在編譯時根據引數類型選取運算式的程式碼。 它類似於 C++ 中的多載,其中引數的類型會選取要呼叫的函式。 在此情況下,引數的類型會選取要評估的運算式。
例如,運算式 _Generic(42, int: "integer", char: "character", default: "unknown");
會評估 42
的類型,並在清單中尋找相符的類型 int
。 它會找到它並傳回 "integer"
。
語法
generic-selection
:
assoc-list
:
association
assoc-list
??association
association
:
第一個 assignment-expression
稱為控制運算式。 控制運算式的類型會在編譯時確定,並與 assoc-list
進行比對以找到要評估及傳回的運算式。 不會評估控制運算式。 例如,_Generic(intFunc(), int: "integer", default: "error");
不會導致在執行階段呼叫 intFunc
。
在確定控制運算式的類型後,會在與 assoc-list
比對之前先移除 const
、volatile
和 restrict
。
不會評估 assoc-list
中未選擇的項目。
限制
assoc-list
不能多次指定相同的類型。assoc-list
無法指定彼此相容的類型,例如列舉和該列舉的基礎類型。- 如果泛型選取沒有預設值,則控制運算式在泛型關聯清單中必須只有一個相容的類型名稱。
範例
使用 _Generic
的一種方法是在巨集中。 <tgmath.h> 標頭檔會使用 _Generic
以根據引數的類型來呼叫正確的數學函數。 例如,cos
的巨集會將浮點型呼叫對應到 cosf
,而將複數雙精確型呼叫對應到 ccos
。
以下範例示範如何撰寫一個巨集來識別您傳遞給它的引數類型。 如果 assoc-list
中沒有項目符合控制運算式,則會產生 "unknown"
:
// 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
*/
需求
使用 /std:c11
編譯。
Windows SDK 10.0.20348.0 (版本 2104) 或更新版本。 請參閱 Windows SDK 以下載最新的 SDK。 如需安裝和使用適用於 C11 和 C17 開發的 SDK 的指示,請參閱在 Visual Studio 中安裝 C11 和 C17 支援。