_Generic:单个值的多个类型?

时间:2015-04-26 05:14:09

标签: c generics generic-programming c11

使用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的支持方式,我_could_制作一个varargs宏来将多个args粘贴到一个值...

#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
....

...有很多这些宏,然后使用varargs包装器自动使用正确的包,请参阅:https://stackoverflow.com/a/24837037/432509

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

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

2 个答案:

答案 0 :(得分:2)

不,类似于switch,没有预见到重新组合_Generic的多个案例的语法。那么你的重组宏方法可能是正确的。您可以通过boost或我的包P99来查看宏元编程,它允许您只有一个这样的宏,它也会对案例进行计数。

答案 1 :(得分:0)

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

_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都具有算术类型。 <{1}} in的剩余部分将是default类型和所有指针类型。

对于您的用法,无论如何,您应该进行此类促销,因为编译器目前以不同方式解释_Complex的控制表达式。例如,有些人还会认为_Generic类型的对象与double const不同。因此,如果您必须区分所有可能的类型资格,这将为您提供很多需要考虑的案例。