基于多个参数的通用选择
如果需要对类型泛型表达式的多个参数进行选择,并且所讨论的所有类型都是算术类型,则避免嵌套 _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)
不评估通用选择的控制表达式。