gpt4 book ai didi

python - 使用宏从 __VA_ARGS__ 生成参数列表

转载 作者:行者123 更新时间:2023-11-28 02:22:39 25 4
gpt4 key购买 nike

只是为了了解一点背景知识,这不是一个微不足道的练习!我正在使用 Boost.Python,为了避免大量丑陋的样板代码,我使用宏将函数包装在 Python 包装器类中,以选择性地为该方法调用 Python 重写(如果存在)。

我已将难题归结为最简单的形式,here :

#include <iostream>

using namespace std;

void foo() { cout << "foo" << endl; }
void bar(char, short, int) { cout <<"bar" << endl; }

#define DEFINE_FUNCTION_WRAPPER(return_type, name, ...)\
return_type name##_wrapper(/* macro expansion */)\
{\
return name(/* macro expansion */);\
}\

DEFINE_FUNCTION_WRAPPER(void, foo) // works!
//DEFINE_FUNCTION_WRAPPER(void, foo, char, short, int) // knowledge insufficient

int main() {
foo_wrapper();
//bar_wrapper(0, 1, 2);
}

虽然这显然适用于 foo,但我的目标是让 DEFINE_FUNCTION_WRAPPER(void, foo, char, short, int) 生成如下所示的函数包装器:

void bar_wrapper(char _1, short _2, int _3)
{
return bar(_1, _2, _3);
}

我希望找到正确的方向来解决这个问题,因为我真的很想掌握这种宏观魔法。

感谢任何帮助!

NOTE: I'm compiling against MSVC C++11.

最佳答案

假设你真的需要宏(我对 Boost.Python 不太熟悉,但是可变参数模板和完美转发与此相同,如果适用的话更清晰),你可以使用几个方便的 Boost.Preprocessor 工具。

要注意的是宏末尾的省略号必须至少有一个参数传递给它;它不能为零。为了解决这个问题,您必须在此过程中的某个地方至少放弃一个参数名称。我选择让宏根据它是否获得任何与参数相关的参数来填充该省略号来选择另外两个宏之一。

#include <boost/preprocessor.hpp>

//generate "type _#"
#define PARAMS(z,n,data) BOOST_PP_TUPLE_ELEM(n,data) _##n

//The first variant: with parameters
//parameters: PARAMS(z,0,(char,short,int)), PARAMS(z,1,(char,short,int)), PARAMS(z,2,(char,short,int))
//call: _0, _1, _2

#define DEFINE_FUNCTION_WRAPPER_WITH_PARAMS(return_type, name, ...)\
return_type name##_wrapper(BOOST_PP_ENUM(BOOST_PP_VARIADIC_SIZE(__VA_ARGS__), PARAMS, (__VA_ARGS__)))\
{\
return name(BOOST_PP_ENUM_PARAMS(BOOST_PP_VARIADIC_SIZE(__VA_ARGS__), _));\
}

//The second variant: no parameters
#define DEFINE_FUNCTION_WRAPPER_WITHOUT_PARAMS(return_type, name)\
return_type name##_wrapper()\
{\
return name();\
}

//choose variant based on whether more than two arguments are passed
#define DEFINE_FUNCTION_WRAPPER(...)\
BOOST_PP_IF(\
BOOST_PP_GREATER(BOOST_PP_VARIADIC_SIZE(__VA_ARGS__), 2), \
DEFINE_FUNCTION_WRAPPER_WITH_PARAMS,\
DEFINE_FUNCTION_WRAPPER_WITHOUT_PARAMS\
)(__VA_ARGS__)

//Clang output:
//void foo_wrapper( char _0 , short _1 , int _2){ return foo( _0 , _1 , _2);}
//int bar_wrapper(){ return bar();}

BOOST_PP_ENUM 用递增的数字调用给定的宏,我们在 PARAMS 宏中使用它作为类型元组(传入的数据)和姓名。它还在扩展之间放置逗号,但不是在最后一个之后。您可以在代码注释中看到它的扩展。如果需要,可以忽略 z

BOOST_PP_ENUM_PARAMS 保存了单独宏的工作,而是采用“常量”来附加数字。它还在扩展之间放置逗号。我们使用下划线以 _0、_1、_2 结尾。

关于python - 使用宏从 __VA_ARGS__ 生成参数列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31845839/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com