我正在编写一个数学库,并希望有一个类似"Add"的调用,它是泛型的,接受两个参数v1和v2,并调用正确的函数.如果v1是ve2,v2是ve2,则它将调用ve2_add,如果v1是ve2,v2是浮点数,则它将调用ve2_AddFloat.但如果v1是ve3,v2是ve3,则它将调用ve3_add等...底部画了一张小图

V1->ve2,v2->ve2:调用ve2_add V1->ve2,v2->Float:调用ve2_addFloat

V1->ve3、v2->ve3:调用ve3_add V1->ve3、v2->Float:调用ve3_addFloat

我确实编写了一个小的泛型代码,如下所示:

#define add(v1, v2) _Generic((v1),                  \
                 vec2: _Generic((v2),           \
                         vec2: vec2_add,        \
                         float: vec2_add_float  \
                         ),             \
                 svec3: _Generic((v2),          \
                         vec3: vec3_add,        \
                         float: vec3_add_float  \
                         )              \
                 )(v1, v2)

由于某些原因,这对ADD_FLOAT类型有效,但当我try 将Vec2添加到Vec2或将Vec3添加到Vec3时,它给出了错误消息:

‘_Generic’ selector of type ‘vec2’ is not compatible with any association
   30 |                              vec3: _Generic((v2),                      \

我到底做错了什么?

推荐答案

这个问题是由"一般 Select "的一个特殊特征引起的,即all个 Select 表达式必须是valid个.当v2vec2时,则表达式_Generic(v2, vec3: vec3_add, float: vec3_add_float)无效,因为vec3float都不与vec2兼容.

国际海事组织,这是一个严重的设计缺陷generic selection.

解决方法是使用default来处理常见情况,即vec2_addv1vec2,或者如果v1vec3,则是vec3_add.

#define add(v1, v2) _Generic((v1),              \
                 vec2: _Generic((v2),           \
                         default: vec2_add,     \
                         float: vec2_add_float  \
                         ),                     \
                 vec3: _Generic((v2),           \
                         default: vec3_add,     \
                         float: vec3_add_float  \
                         )                      \
                 )(v1, v2)

C++相关问答推荐

为指针 struct 创建宏

是否有任何情况(特定类型/值),类型双关在所有符合标准的C实现中产生相同的行为?

字符串令牌化xpath表达式

exit(EXIT_FAILURE):Tcl C API类似功能

减法运算结果的平方的最快方法?

当我运行/调试C程序时,Malloc()似乎正在将&q;r\r...&q;赋值给一个指针,我不确定为什么?

识别和处理c中整数溢出的最佳方法?

Clang警告称,`ffi_type`与`sizeof`不兼容

为什么我可以在GCC的标签后声明变量,但不能声明Clang?

类型定义 struct 与简单的类型定义 struct

对于STM32微控制器,全局偏移表.get和.Got.plt必须为零初始化

为什么我的二叉树删除删除整个左部分的树?

问题:C#Define上的初始值设定项元素不是常量

如何在C中处理流水线中的a、n命令?

C中的空指针是什么(_N)?

';malloc():损坏的顶部大小';分配超过20万整数后

Leet代码运行时错误:代码不会在Leet代码上编译,而是在其他编译器中编译,如netbeans和在线编译器

令人困惑的返回和 scanf 问题相关

在C中定义函数指针?

使用复合文字数组初始化的指针数组