_Generic:多个类型到一个值?

_Generic: multiple types to a single value?

使用 c11 _Generic 有没有办法将多个类型映射到一个值?

例如:

_Generic(e,      \
    A *:    foo_expression, \
    B **:   foo_expression, \
    C:      foo_expression, \
    enum D: bar_expression, \
    void *: bar_expression)

有没有办法对类型进行分组? (这不是仅用于表达意图的有效语法)

_Generic(e, \
    A *: B **: C:    foo_expression, \
    enum D: void *:  bar_expression)

我问的原因是 args foobaz 最终会变成大表达式 (不一定能重构为函数),所以避免大量重复的方法会很好。


注:

如果没有支持的方法使用 _Generic,我_可以_制作一个可变参数宏来将多个参数粘合到一个值...

#define GENERIC_TYPE_GLUE3(answer, arg0, arg1) \
    arg0: answer, arg1: answer
#define GENERIC_TYPE_GLUE4(answer, arg0, arg1, arg2) \
    arg0: answer, arg1: answer, arg2: answer
....

...有很多这样的宏,然后使用可变参数包装器自动使用正确的,请参阅:

_Generic(e,      \
    GENERIC_TYPE_GLUE(foo_expression, short int, long),
    GENERIC_TYPE_GLUE(bar_expression, float, double))

(参见工作示例:https://gist.github.com/ideasman42/4426f255880ff6a53080

对于您的用例,您可以使用类型提升规则

_Generic((e)+0ULL,             \
    unsigned long long:   foo, \
    default:  bar)

如果你有浮点数以外的其他情况,你甚至可以更进一步

_Generic((e)+0ULL,             \
    unsigned long long:   foo, \
    default: _Generic((e)+0.0L,\
     long double:   bar,       \
     default:  blur))

这假设您所有的表达式 e 都具有算术类型。剩下的 default 将是 _Complex 类型和所有指针类型。

无论如何,对于您想要的那种用法,您应该进行此类提升,因为编译器当前以不同方式解释 _Generic 的控制表达式。例如,有些人还会认为 double const 类型的对象不同于 double。因此,如果您必须区分所有可能的类型限定条件,那么这确实会给您很多需要考虑的情况。

不,与 switch 类似,没有预见到可以为 _Generic 重新组合多个案例的语法。那么,您的重组宏方法可能是适合您目的的正确方法。您可以查看由 boost 或我的包 P99 完成的宏元编程,它允许您只有一个这样的宏,它还可以计算案例。