【问题标题】:Is there an easier way to do a macro to define a function with variable amount of arguments?有没有更简单的方法来做一个宏来定义一个具有可变数量参数的函数?
【发布时间】:2014-07-08 20:47:39
【问题描述】:

我有一个宏,它定义了一个带有可变数量参数的函数,该宏有一些逻辑来决定必须调用哪个真正的函数。我目前的做法如下:

#define FUNC(ret,args,args_call) \
    ret my_func(args) { \
        if( something ) other_func(args_call);\
        return one_func(args_call);\
    }
#define PARAM(...) __VA_ARGS__

我是这样用的:

class AClass : public AInterface {
public:
    FUNC(int,PARAM(int a, int b),PARAM(a,b))
};

我想知道是否有更好的方法来做到这一点。

注意:声明的(在我的示例中为my_func)函数将用于重新实现超类中的方法,因此使用模板(我知道的那些)的方法不会解决我的问题。

Edit2:即使使用适当的可变参数模板函数,我仍然需要宏来声明函数,因为它覆盖了超类中的函数。

#define FUNC(ret,args,args_call) \
ret my_func(args) { \
    return proper_variadic_templated_function<ret>(args_call);\
}

【问题讨论】:

  • 我猜在 Stackoverflow 的某处有一些重复,但我没有找到与此问题相关的任何内容,因为我不知道如何正确表达这个问题。
  • 你听说过可变参数模板吗?
  • @AndréPuel 那为什么不写一个合适的转发可变参数模板函数呢?你真的需要宏吗?
  • 对我来说,这似乎完全是错误的......要获得一个好的答案,您可能应该描述您所看到的实际问题,而不是询问您的首选解决方案。又名“你在问一个 XY 问题”。
  • @MatsPetersson stackoverflow.com/questions/24643183/… 你去吧

标签: c++ c-preprocessor variadic-macros


【解决方案1】:

如果我们使用前两个代码块here 中的EVAL、助手和条件宏。我们可以创建一些递归宏来解析参数数组。

由于逗号是句法,我们需要对其进行转义才能输出。

#define COMMA() ,

我们可以生成两个函数来区分类型和名称。

#define I_WT_R() I_WT
#define I_WT(t,v,n,...) \
    t v IS_DONE(n)(      \
        EAT               \
    ,                      \
       OBSTRUCT(COMMA)()    \
       OBSTRUCT(I_WT_R)()    \
    )(n,__VA_ARGS__)
#define WithTypes(...) I_WT(__VA_ARGS__,DONE)

还有。

#define I_WoT_R() I_WoT
#define I_WoT(t,v,n,...) \
    v IS_DONE(n)(         \
        EAT                \
    ,                       \
        OBSTRUCT(COMMA)()    \
        OBSTRUCT(I_WoT_R)()   \
    )(n,__VA_ARGS__)
#define WithoutTypes(...) I_WoT(__VA_ARGS__,DONE)

重新定义你的宏:

#define FUNC(ret,args) EVAL(                           \
    ret my_func(WithTypes args) {                      \
        if( something ) other_func(WithoutTypes args); \
        return one_func(WithoutTypes args);            \
    })

允许您使用稍微更好的语法:

class AClass : public AInterface {
public:
    FUNC(int,(int,a,int,b))
};

编译为(添加换行符后):

class AClass : public AInterface {
public:
    int my_func(int a , int b ) {
        if( something )
            other_func(a , b );
        return one_func(a , b );
    }
};

希望对您有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-26
    • 2013-01-18
    • 1970-01-01
    • 2019-01-15
    • 1970-01-01
    • 2014-11-13
    相关资源
    最近更新 更多