使用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 foo
和baz
最终可能会成为大型表达式(无法将其重构为函数),所以一种方式避免大量重复会很好。
注意:
如果没有使用_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)
答案 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
不同。因此,如果您必须区分所有可能的类型资格,这将为您提供很多需要考虑的案例。