c - 是否可以动态定义_Generic 的关联列表?
问题描述
我有一个这样的模板:
template.h
----------
// Declare a function "func_type()"
void JOIN(func_, T)(T t) { return; }
#undef T
我这样使用它来为不同类型生成相同的函数:
example.c
---------
#define T int
#include "template.h"
#define T float
#include "template.h"
我想要一个func
可以用来代替funct_int
,func_float
等的单曲。我的问题_Generic
是似乎无法动态定义关联列表。实际上,我想要这样的东西:
#define func(TYPE) _Generic((TYPE), AUTO_GENERATED_LIST)
而不是像这样手动定义每个新类型:
#define func(TYPE) _Generic((TYPE), int: func_int..., float: func_float...)
这是一个不起作用的代码示例:https ://ideone.com/HN7sst
解决方案
我认为您想要做的事情可以通过可怕的“X 宏”来实现。创建一个列表,例如
#define SUPPORTED_TYPES(X) \
X(int, "%d") \
X(float, "%f") \
类型在哪里int
,在这种情况下,我使用 printf 格式说明符作为另一个项目。这些可以是任何算作有效预处理器令牌的东西。
然后你可以通过一个邪恶的宏生成所有函数,如下所示:
#define DEFINE_F(type, fmt) \
void f_##type (type param) \
{ printf(fmt "\n", param); }
SUPPORTED_TYPES(DEFINE_F)
这会创建诸如void f_int (int param) { printf("%d\n", param); }
. 也就是说,与 C++ 模板非常相似——函数做同样的事情但类型不同。
然后,您可以像这样编写 _Generic 宏:
void dummy (void* param){}
#define GENERIC_LIST(type, fmt) type: f_##type,
#define func(x) _Generic((x), SUPPORTED_TYPES(GENERIC_LIST) default: dummy)(x)
在这里定义通用 asoc。列出GENERIC_LIST
,使用该type
项目,但忽略其他所有内容。所以它扩展到例如int: f_int,
。
一个问题是旧的“尾随逗号”问题,我们不能像_Generic((x), int: f_int,)(x)
逗号之后那样写 _Genericf_int
会弄乱语法。我用一个调用虚拟函数的子句解决了这个问题default
,不理想......可能想assert
在那个函数里面加上一个。
完整示例:
#include <stdio.h>
#define SUPPORTED_TYPES(X) \
X(int, "%d") \
X(float, "%f") \
#define DEFINE_F(type, fmt) \
void f_##type (type param) \
{ printf(fmt "\n", param); }
SUPPORTED_TYPES(DEFINE_F)
void dummy (void* param){}
#define GENERIC_LIST(type, fmt) type: f_##type,
#define func(x) _Generic((x), SUPPORTED_TYPES(GENERIC_LIST) default: dummy)(x)
int main (void)
{
int a = 1;
float b = 2.0f;
func(a);
func(b);
}
输出:
1
2.000000
这是 100% ISO C,没有扩展。
推荐阅读
- python - 具有急切执行的 TensorFlow 多项式分布
- angular - 从 7.2.15 升级角度时出错:minTimeout 大于 maxTimeout
- spring - model.addAttribute 返回 null?
- angular - 从一个类中的另一个方法调用方法(this.function 不起作用)
- python - 添加批量标准化会降低性能
- image-processing - 如何将 DynamicImage 转换为 Base64?
- reactjs - 检测 React 组件外部的点击和悬停的单个状态
- android - 如何使用 Dagger 2 @Provide 提供服务
- vue.js - 下载文件时如何重命名?
- javascript - Sharepoint:如何使用一组项目 ID 检查每个项目是否存在于列表中?