一般選取 (C11)
_Generic
使用 關鍵字來撰寫根據引數類型在編譯時期選取運算式的程式碼。 類似于 C++ 的多載,其中引數的類型會選取要呼叫的函式。 在此情況下,引數的類型會選取要評估的運算式。
例如,運算式 _Generic(42, int: "integer", char: "character", default: "unknown");
會評估 的類型 42
,並在清單中尋找相符的類型 int
。 它會尋找它並傳 "integer"
回 。
語法
generic-selection
:
_Generic
(assignment-expression
, assoc-list
)
assoc-list
:
association
assoc-list
, association
association
:
type-name
: assignment-expression
default
: assignment-expression
第一個 assignment-expression
稱為控制運算式。 控制運算式的類型是在編譯時期決定,並比對 assoc-list
,以尋找要評估並傳回的運算式。 不會評估控制運算式。 例如, _Generic(intFunc(), int: "integer", default: "error");
不會在執行時間 intFunc
對 產生呼叫。
決定控制運算式的類型時, const
會先移除 、 volatile
和 restrict
,然後再比對 assoc-list
。
不會評估未選擇之 assoc-list
中的專案。
條件約束
assoc-list
無法多次指定相同的類型。assoc-list
無法指定彼此相容的型別,例如列舉型別和該列舉的基礎型別。- 如果泛型選取範圍沒有預設值,控制運算式在泛型關聯清單中必須只有一個相容的類型名稱。
範例
其中一個使用 _Generic
方式是在宏中。 根據 < 引數的類型,tgmath.h > 標頭檔會使用 _Generic
來呼叫正確的數學函式。 例如, 的 cos
宏會將具有 float 的呼叫對應至 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。 如需安裝和使用 SDK 以進行 C11 和 C17 開發的指示,請參閱 在 Visual Studio 中安裝 C11 和 C17 支援。
另請參閱
意見反應
https://aka.ms/ContentUserFeedback。
即將登場:在 2024 年,我們將逐步淘汰 GitHub 問題作為內容的意見反應機制,並將它取代為新的意見反應系統。 如需詳細資訊,請參閱:提交並檢視相關的意見反應