如何使用宏或元编程在C++中创建'passthru'功能?

Rya*_*yan 7 c++ macros metaprogramming

所以我有一系列全球功能,比如说:

foo_f1(int a, int b, char *c);
foo_f2(int a);
foo_f3(char *a);
Run Code Online (Sandbox Code Playgroud)

我想围绕这些做一个C++包装,比如:

MyFoo::f1(int a, int b, char* c); 
MyFoo::f2(int a);
MyFoo::f3(char* a);
Run Code Online (Sandbox Code Playgroud)

大约有40个这样的函数,其中35个我只想传递给全局函数,另外5个我想做一些与之不同的函数.

理想情况下,MyFoo.cpp的实现类似于:

PASSTHRU( f1, (int a, int b, char *c) );
PASSTHRU( f2, (int a) );

MyFoo::f3(char *a)
{
   //do my own thing here
}
Run Code Online (Sandbox Code Playgroud)

但是我很难找到一种优雅的方法来制作上面的PASSTHRU宏.

我真正需要的是像下面神话般的X getArgs():

MyFoo::f1(int a, int b, char *c)
{
  X args = getArgs();
  args++; //skip past implicit this..
  ::f1(args);  //pass args to global function 
}
Run Code Online (Sandbox Code Playgroud)

但是,如果没有进入汇编,我找不到getArgs()的良好实现.

Geo*_*che 10

您可以使用Boost.Preprocessor来实现以下功能:

struct X {
    PASSTHRU(foo, void, (int)(char))
};
Run Code Online (Sandbox Code Playgroud)

...扩展到:

struct X {
    void foo ( int arg0 , char arg1 ) { return ::foo ( arg0 , arg1 ); }
};
Run Code Online (Sandbox Code Playgroud)

...使用这些宏:

#define DO_MAKE_ARGS(r, data, i, type) \
  BOOST_PP_COMMA_IF(i) type arg##i

#define PASSTHRU(name, ret, args) \
  ret name ( \
    BOOST_PP_SEQ_FOR_EACH_I(DO_MAKE_ARGS, _, args) \
  ) { \
    return ::name ( \
      BOOST_PP_ENUM_PARAMS(BOOST_PP_SEQ_SIZE(args), arg) \
    ); \
  }
Run Code Online (Sandbox Code Playgroud)


小智 5

在40多个函数中,您可以在一小时内手动输入包装器.编译器将检查结果的正确性.假设每个需要换行的新功能需要额外2分钟,签名更改需要额外1分钟.

按照规定,并没有提及频繁的更新或更改,听起来这个问题并不需要狡猾的解决方案.

因此,我的建议是保持简单:手工完成.将原型复制到源文件中,然后使用键盘宏(emacs/Visual Studio/vim)进行修复,和/或多次搜索和替换,生成一组定义和一组声明.剪切声明,粘贴到标题中.填写非传递函数的定义.这不会赢得任何奖项,但它很快就会结束.

没有额外的依赖,没有新的构建工具,适用于代码浏览/标签/ intellisense /等,适用于任何调试器,没有专门的语法/现代功能/模板/等,所以任何人都可以理解结果.(确实没有人会留下深刻的印象 - 但这将是一种不受欢迎的好事.)