C11中_Generic如何添加类型

4

如何向c11 _Generic函数添加额外的类型?

你是否必须要 #undef / 重新 #define 它?(如果是这样,下面的方法可行吗?)或者有更好的方式吗?

#define to_str(X) _Generic((X), \
    long double: ld_str, \
    double: d_str, \
    float: f_str, \
    )(X)

#undef to_str

#define to_str(X) _Generic((X), \
    long double: ld_str, \
    double: d_str, \
    float: f_str, \
    int: i_str, \
    )(X)
3个回答

8

我不确定我完全理解你的问题。您是指您有一个由某个库提供的类型通用宏,您想使用自己的新类型进行修改吗?

您可以给它另一个名称,并使用默认情况来获得提供的行为:

#define to_str2(X) _Generic((X), default: to_str(X), int: i_str(X))

编辑:

这种方法并不完美,因为你必须将函数参数评估放在_Generic中。这意味着特别需要注意的是X的类型必须与嵌套泛型表达式的所有分支兼容。

如果涉及的库有一个宏可以仅返回函数本身,而不含(X),称为to_strGen,且从不评估X,那么做法会更容易些:

#define to_str2Gen(X) _Generic((X), default: to_strGen(X), int: i_str)
#define to_str2(X) to_str2Gen(X)(X)

注意:如果原始的宏没有定义“default”选择,则封装将无法工作。请参见comp.lang.c上的线程“Nested_Generic selections”(https://groups.google.com/d/topic/comp.lang.c/1RQvT2a5DF0/discussion)。 - J. C. Salomon
@J.C.Salomon,我认为缺少default并不是问题,而是我认为X与类型泛型表达式的所有分支的兼容性是问题。请参见我的编辑。 - Jens Gustedt

3
如果这是你的代码,你需要使用 #undef 取消定义并重新使用 #define 进行定义。目前没有扩展类型通用表达式的方法(据我所知)。
如果这不是你的代码,我会像Jens建议的那样引入一个带有扩展的第二个表达式。

1
有一件事你可以做的是:
#define to_str(X) _Generic((X), \
    long double: ld_str, \
    double: d_str, \
    float: f_str \
    EXTRA_TYPES \
    )(X)

#define EXTRA_TYPES \
,int: i_str, \
char: c_str

注意逗号是EXTRA_TYPES的一部分,而不是to_str宏的一部分。这是为了使to_str即使EXTRA_TYPES为空也能正常工作。
现在你只需要定义EXTRA_TYPES并列出你需要的类型即可。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接