我们说我有一些名为variant
的未指定类型,以及两个允许转换为此类型的函数,具有以下签名:
struct converter
{
template<typename T>
static variant to(const T&);
template<typename T>
static T from(const variant&);
};
现在,我要做的是为任意C ++函数创建包装器,如下例所示:
SomeObject f_unwrapped(const std::string& s, int* x)
{
//... do something with the inputs...
return SomeObject();
}
extern "C" variant f(variant s, variant x)
{
return converter::to<SomeObject>(f_unwrapped(converter::from<std::string>(s), converter::from<int*>(x)));
}
理想情况下,我希望包装器是一行声明或宏,只需要f_unwrapped
函数和名称f
作为输入。
我试图将函数包装到函数对象中,然后使用可变参数模板进行官僚作业。虽然这确实有效,但我不知道如何制作结果函数extern "C"
。
实现这一目标的最惯用方式是什么?
答案 0 :(得分:0)
如果我们使用前两个代码块here中的EVAL,helper,Conditional和map宏。</ p>
为了满足我们的需求,地图需要更加通用。
#define MM1() MM_CALL1
#define MM_NEXT1(Macro,a,...) \
IS_DONE(a)( \
EAT \
, \
OBSTRUCT(COMMA)() OBSTRUCT(MM1)() \
) \
(Macro,a,__VA_ARGS__)
#define MM_CALL1(Macro,a,...) \
Macro(a) \
MM_NEXT1(Macro,__VA_ARGS__)
#define MacroMap1(Macro,...) MM_CALL1(Macro,__VA_ARGS__,DONE)
#define MM2() MM_CALL2
#define MM_NEXT2(Macro,a,...) \
IS_DONE(a)( \
EAT \
, \
OBSTRUCT(COMMA)() OBSTRUCT(MM2)() \
) \
(Macro,a,__VA_ARGS__)
#define MM_CALL2(Macro,a,b,...) \
Macro(a,b) \
MM_NEXT2(Macro,__VA_ARGS__)
#define MacroMap2(Macro,...) MM_CALL2(Macro,__VA_ARGS__,DONE)
我们还希望来自here的WithTypes
和WithoutTypes
。
我们可以定义AMACRO
来完成您想要的工作。
#define AsVariant(param) variant param
#define ConvertFrom(type,param) converter::from<type>(param)
#define HEADDER(type,func,params) type func ##_unwrapped (WithTypes params)
#define WRAPPER(type,func,params) \
extern "C" variant func (OBSTRUCT(MacroMap1)(AsVariant,WithoutTypes params)) \
{ \
return converter::to< type >(func ## _unwrapped( \
MacroMap2(ConvertFrom,IDENT params) \
)); \
}
#define AMACRO(type,func,params) \
EVAL( \
HEADDER(type,func,params); \
WRAPPER(type,func,params) \
HEADDER(type,func,params) \
)
这将转变为:
AMACRO(SomeObject,f,(const std::string&, s, int*, x))
{
// ... do something with the inputs ...
return SomeObject();
}
进入此(格式化后):
SomeObject f_unwrapped (const std::string& s , int* x );
extern "C" variant f (variant s , variant x )
{
return converter::to<SomeObject>(f_unwrapped(converter::from<const std::string&>(s),converter::from<int*>(x)));
}
SomeObject f_unwrapped (const std::string& s , int* x )
{
return SomeObject();
}
注意:强>
如果const
需要从参数中移除,则可以制作类似于ISDONE
的条件,并将其添加到ConvertFrom
宏。