_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 foo
和 baz
最终会变成大表达式 (不一定能重构为函数),所以避免大量重复的方法会很好。
注:
如果没有支持的方法使用 _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 完成的宏元编程,它允许您只有一个这样的宏,它还可以计算案例。
使用 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
,我_可以_制作一个可变参数宏来将多个参数粘合到一个值...
#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 完成的宏元编程,它允许您只有一个这样的宏,它还可以计算案例。