繁体   English   中英

可变参数宏中的C ++可变参数模板

[英]C++ variadic templates function in variadic macro

我目前正在开展一个项目,我需要简化现有系统。 进入细节问题是我得到了一些函数指针(来自type: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));\
}

这就是问题所在。 (我认为)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);

我收到以下错误:“严重性代码说明项目文件行抑制状态错误(活动)不完整类型不允许[...] \\ main.cpp 34”

所以我的问题是,我做错了什么? 这个问题真的与DEFINE_FUNCTION宏中的Params有关,还是我错过了什么?

我使用宏,但我不会称自己为这方面的专家。 但我理解的方式是(DECLARE_PARAMS Params)应该将参数扩展为:

int a_, int b_

扫描后,我希望以下代码:

void Gen_ThatFunction(int a_, int b_)
{
    return GetFunction<void>(ThatFunction, a_, b_) (a_, b_);
}

测试Directcall宏:使用以下代码测试了directcall宏的功能

因此我更改了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* (或函数)的返回类型和名称是前两个参数。 接下来是括号括起来的参数类型列表,包含的参数名称,最后是封闭的类型AND名称。 就像我说的那样,笨重。

这将生成函数:

void Gen_ThatFunction (int a_, int b_) { return reinterpret_cast<void(*)(int, int)>(ThatFunction) (a_, b_); }

然后,您可以根据需要调用该函数:

Gen_ThatFunction(2, 3); //prints "2 * 3 = 6"

当然,请记住这是微软特有的。 这里,括号括起来的逗号分隔项是单个宏参数。 在任何其他编译器上,这将不起作用(我知道)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM