如何获得通过preprocessor函数签名之前定义写到? [英] How to get function signature via preprocessor define written before it?

查看:128
本文介绍了如何获得通过preprocessor函数签名之前定义写到?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建一个定义来分析函数签名和使用Boost preprocessor创造的东西是这样的:

I want to create a define to parse function signature and using Boost Preprocessor create something like this:

MY_DEFINE std::string fun(int t, float b)
{

或至少

MY_DEFINE(std::string)(fun)(int t, float b)
{

这会产生:

class fun_in
{
    int t;
    float b;
}

class fun_out
{
    std::string value;
}

void my_fun_wrapper(int t, float b)
{
}

std::string fun(int t, float b)
{
    my_fun_wrapper(t, b);

对于每个功能定义。

for each function with that define.

是否有可能创造这样定义的 N 传入的参数,并通过加速preprocessor任何返回类型函数包装?

Is it possible to create such define wrapper for function of N incoming arguments and any return type via Boost Preprocessor?

推荐答案

那么,preprocessor无法解析没有pre-告诉它的令牌。所以,你需要使用更多的括号来代替。下面是它会是什么样子:

Well, the preprocessor can't parse tokens without pre-telling it. So you will need to use a lot more parenthesis instead. Here's what it would look like:

DEFINE( (std::string)(fun)((int) a, (float) b) )
{
    return "Hello World!";
}

下面是如何创建使用boost宏(我假设你熟悉它的preprocessor库)。首先是定义一些宏处理括号,因为升压根本不处理与逗号序列:

Here's how to create the macro using boost(I assume you are familiar with its preprocessor library). First is to define some macros for handling parenthesis, because boost doesn't handle sequences with commas at all:

#define REM(...) __VA_ARGS__
#define EAT(...)

// Retrieve the type
#define TYPEOF(x) DETAIL_TYPEOF(DETAIL_TYPEOF_PROBE x,)
#define DETAIL_TYPEOF(...) DETAIL_TYPEOF_HEAD(__VA_ARGS__)
#define DETAIL_TYPEOF_HEAD(x, ...) REM x
#define DETAIL_TYPEOF_PROBE(...) (__VA_ARGS__),
// Strip off the type
#define STRIP(x) EAT x
// Show the type without parenthesis
#define PAIR(x) REM x

接下来,你需要处理ARGS以三种不同的方式。首先,是对他们输出作为成员变量(如 int类型的;浮动B:)。那么作为函数的参数(如(int类型的,浮动B))。后来总算是向前迈出的参数沿着其他功能(如(A,B))。

Next, you need to handle the args in three different ways. First, is to output them as member variable(like int a; float b;). Then as functions arguments(like (int a, float b)). Then finally as forward arguments to pass along to the other function(like (a, b)).

#define DETAIL_DEFINE_MEMBERS_EACH(r, data, x) PAIR(x);
#define DETAIL_DEFINE_ARGS_EACH(r, data, i, x) BOOST_PP_COMMA_IF(i) PAIR(x)
#define DETAIL_DEFINE_FORWARD_EACH(r, data, i, x) BOOST_PP_COMMA_IF(i) STRIP(x)

#define DETAIL_DEFINE_MEMBERS(args) BOOST_PP_SEQ_FOR_EACH(DETAIL_DEFINE_MEMBERS_EACH, data, BOOST_PP_VARIADIC_TO_SEQ args)
#define DETAIL_DEFINE_ARGS(args) BOOST_PP_SEQ_FOR_EACH_I(DETAIL_DEFINE_ARGS_EACH, data, BOOST_PP_VARIADIC_TO_SEQ args)
#define DETAIL_DEFINE_FORWARD(args) BOOST_PP_SEQ_FOR_EACH_I(DETAIL_DEFINE_FORWARD_EACH, data, BOOST_PP_VARIADIC_TO_SEQ args)

接下来,我们创建三个参数一个 DETAIL_DEFINE 宏。第一个是功能,参数,然后将返回值的名称。这将产生类和函数,就像你想要的:

Next we create a DETAIL_DEFINE macro that take three parameters. The first is the name of the function, the arguments, and then the return value. This will produce the classes and functions, like you want:

#define DETAIL_DEFINE(name, args, ...) \
struct BOOST_PP_CAT(name, _in) \
{ \
    DETAIL_DEFINE_MEMBERS(args) \
}; \
struct BOOST_PP_CAT(name, _out) \
{ \
    __VA_ARGS__ value; \
}; \
__VA_ARGS__ BOOST_PP_CAT(name, _impl) DETAIL_DEFINE_ARGS(args) ; \
__VA_ARGS__ name DETAIL_DEFINE_ARGS(args) \
{ \
    return BOOST_PP_CAT(name, _impl) DETAIL_DEFINE_FORWARD(args); \
} \
__VA_ARGS__ BOOST_PP_CAT(name, _impl) DETAIL_DEFINE_ARGS(args)

最后,定义宏将解析出所有的括号,并将其传递给 DETAIL_DEFINE 宏:

Finally, the DEFINE macro will parse out all the parenthesis and pass them to the DETAIL_DEFINE macro:

#define DEFINE(x) DETAIL_DEFINE(TYPEOF(STRIP(x)), (TYPEOF(STRIP(STRIP(x)))), TYPEOF(x))

所以,现在当你写:

So now when you write:

DEFINE( (std::string)(fun)((int) a, (float) b) )
{
    return "Hello World!";
}

这应该输出:

struct fun_in
{
    int a;
    float b;
};
struct fun_out
{
    std::string value;
};
std::string fun_impl(int a, float b);
std::string fun(int a, float b)
{
    return fun_impl(a, b);
}
std::string fun_impl(int a, float b)
{
    return "Hello World!";
}

请注意,这不会在MSVC工作,也有变通方法,但。此外,您还需要编译 -DBOOST_PP_VARIADICS = 1

Note that this won't work in MSVC, there are workarounds though. Also, you need to compile with the -DBOOST_PP_VARIADICS=1.

这篇关于如何获得通过preprocessor函数签名之前定义写到?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆