基於多個引數的通用選擇
如果需要對型別泛型表示式的多個引數進行選擇,並且所討論的所有型別都是算術型別,則避免巢狀 _Generic
表示式的簡單方法是使用控制表示式中的引數的新增:
int max_int(int, int);
unsigned max_unsigned(unsigned, unsigned);
double max_double(double, double);
#define MAX(X, Y) _Generic((X)+(Y), \
int: max_int, \
unsigned: max_unsigned, \
default: max_double) \
((X), (Y))
這裡,控制表示式 (X)+(Y)
僅根據其型別進行檢查而不進行評估。執行算術運算元的常規轉換以確定所選型別。
對於更復雜的情況,可以通過將它們巢狀在一起來基於操作符的多個引數進行選擇。
此示例在四個外部實現的函式之間進行選擇,這兩個函式採用兩個 int 和/或字串引數的組合,並返回它們的總和。
int AddIntInt(int a, int b);
int AddIntStr(int a, const char* b);
int AddStrInt(const char* a, int b );
int AddStrStr(const char* a, const char* b);
#define AddStr(y) \
_Generic((y), int: AddStrInt, \
char*: AddStrStr, \
const char*: AddStrStr )
#define AddInt(y) \
_Generic((y), int: AddIntInt, \
char*: AddIntStr, \
const char*: AddIntStr )
#define Add(x, y) \
_Generic((x) , int: AddInt(y) , \
char*: AddStr(y) , \
const char*: AddStr(y)) \
((x), (y))
int main( void )
{
int result = 0;
result = Add( 100 , 999 );
result = Add( 100 , "999" );
result = Add( "100" , 999 );
result = Add( "100" , "999" );
const int a = -123;
char b[] = "4321";
result = Add( a , b );
int c = 1;
const char d[] = "0";
result = Add( d , ++c );
}
即使看起來好像引數 y
被評估不止一次,它也不是 1 。兩個引數僅在巨集 Add:( x , y )
的末尾進行一次計算,就像在普通的函式呼叫中一樣。
1 (引用自:ISO:IEC 9899:201X 6.5.1.1 通用選擇 3)
不評估通用選擇的控制表示式。