C++可变参数模板在可变参数宏中起作用
C++ variadic templates function in variadic macro
我目前正在做一个项目,我需要简化现有系统。如果不深入细节,问题是我得到了一些函数指针(来自类型:void*(,我需要从中创建一个函数(= 创建一个带有签名的函数(。所以我的方法是创建以下可变参数模板函数:
template <typename ReturnType, typename ... Params>
ReturnType(*GetFunction(void* func, Params ...)) (Params ...)
{
return reinterpret_cast<ReturnType(*) (Params ...)> (func);
}
现在我需要一种方法来创建所需的函数:
#define DECLARE_PARAMS(...) __VA_ARGS__
#define Define_Function(returnType, fname, Params) returnType Gen_##fname (DECLARE_PARAMS Params)
{
return FUNCTION_DIRECTCALL(returnType, fname, (DECLARE_PARAMS Params));
}
这就是问题所在。(我认为(参数不会扩展它们应该扩展的方式。但我不知道为什么?
我用硬编码值测试了DEFINE_FUNCTION宏中的FUNCTION_DIRECTCALL(简单地将定义放入直接调用中(并且它有效,所以应该没有错误,但我愿意改进
#define FUNCTION_DIRECTCALL(returnType, functionName, ...)
GetFunction<returnType>(functionName, DECLARE_PARAMS __VA_ARGS__) ( DECLARE_PARAMS __VA_ARGS__)
如果我尝试使用宏定义一个函数
Define_Function(void, ThatFunction, (int a_, int b_)); // void ThatFunction(int a, int b);
我收到以下错误:"严重性代码描述项目文件行抑制状态错误(活动(不允许不完整的类型 [...]\主.cpp 34">
所以我的问题是,我做错了什么?问题真的与DEFINE_FUNCTION宏中的参数有关还是我错过了什么?
我使用宏,但我不会称自己为这方面的专家。但我的理解是(DECLARE_PARAMS参数(应该将参数扩展到:
int a_, int b_
扫描后,我希望使用以下代码:
void Gen_ThatFunction(int a_, int b_)
{
return GetFunction<void>(ThatFunction, a_, b_) (a_, b_);
}
测试直接调用宏:使用以下代码,我测试了直接调用宏的功能
因此,我更改了Define_Function宏:
#define Define_Function(returnType, fname, Params) returnType Gen_##fname (DECLARE_PARAMS Params)
{
int a = 2, b = 3;
return FUNCTION_DIRECTCALL(void, ThatFunction, (a, b) );
}
ThatFunction的定义:
void ThatFunction(int a, int b)
{
std::cout << a << " * " << b << " = " << b * a << std::endl;
}
输出:"2 * 3 = 6">
所有代码在VC++ 2015中编译
我知道如何做你要求的唯一方法真的很笨拙。
#define DEFINE_FUNCTION(RET, NAME, TYPES, NAMES, BOTH) RET Gen_##NAME BOTH { return reinterpret_cast<RET(*)TYPES>(NAME) NAMES; }
你像这样使用它:
DEFINE_FUNCTION(void, ThatFunction, (int, int), (a_, b_), (int a_, int b_))
返回类型和void*
(或函数(的名称是前两个参数。接下来是用括号括起来的参数类型列表,也括起来的参数名称,最后是括起来的类型和名称。就像我说的,笨重。
这将生成函数:
void Gen_ThatFunction (int a_, int b_) { return reinterpret_cast<void(*)(int, int)>(ThatFunction) (a_, b_); }
然后,您可以根据需要调用该函数:
Gen_ThatFunction(2, 3); //prints "2 * 3 = 6"
当然,请记住,这是Microsoft具体的。在这里,用括号括起来的逗号分隔的项目是单个宏参数。在任何其他编译器上,这都不起作用(我知道(。
- 在不传递参数数量且只有3个点的情况下,如何使用变差函数
- 如何使用可变参数模板强制转换每个变体类型
- 关于如何在具有单个参数的变体构造中选择替代方案?
- 调用参数排列不变函数 f(i++, i++)
- 参数归纳与标准::变体
- 模板化回调参数的逆变,如 C# 中的逆变
- 如何在没有参数包的情况下编写变差函数
- 通过具有嵌套类的工厂类获取多个变异类模板参数包
- 获取模板参数的成员变量值列表
- 保留短 lambda 用作函数的中间参数,使用 clang 格式保持不变
- 如何定义变体<x,y,z>提取模板参数的子类型
- 正确对齐内存模板,参数顺序不变
- 递归中不同参数类型的变元模板函数
- 通过函数指针传递给变差函数的参数会更改其值
- 提升预定义为带有参数的全局 lambda 的变体访问者
- 使用可变参数模板参数提升变体访问者
- boost ::变体 - 为什么模板参数比const字符串参数具有更高的优先级
- 将变参数包中的值加载到临时数组中
- 使用额外参数提升变体访客
- 正在将动态数组元素解析为参数?(变音符)