使用常规类BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS可以工作:
>> more dummy.cpp
#include <boost/python.hpp>
using namespace boost::python;
class X
{
public:
X() {};
int twice(int x=5, float y=2.) {return (int)(x*y);};
};
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(X_twice_overloads, X::twice, 0, 2)
BOOST_PYTHON_MODULE(dummy)
{
class_<X>("X").def("twice", &X::twice, X_twice_overloads(args("x", "y")));
}
>> make
g++ -I /usr/include/python2.7 -o dummy.so -fPIC -shared dummy.cpp -lboost_python -lpython2.7
>> python
Python 2.7.17 (default, Oct 19 2019, 23:36:22)
[GCC 9.2.1 20191008] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import dummy; dx = dummy.X(); print dx.twice(), dx.twice(2,-1.)
10 -2
好的,可以。现在,我需要使用一个(仅)类型T“]”类化“一个类:
>> more dummyT.cpp
#include <string>
#include <boost/python.hpp>
using namespace boost::python;
template<typename T>
class Y
{
public:
Y() {};
T twice(T x=5, float y=2.) {return (T)(x*y);};
};
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(Yint_twice_overloads, Y<int>::twice, 0, 2)
template<typename T, typename O>
void exportY(std::string type)
{
class_<Y<T>>(type.c_str()).def("twice", &Y<T>::twice, O(args("x", "y")));
};
BOOST_PYTHON_MODULE(dummyT)
{
exportY<int, Yint_twice_overloads>("Yint");
}
>> make dummyT
g++ -I /usr/include/python2.7 -o dummyT.so -fPIC -shared dummyT.cpp -lboost_python -lpython2.7
>> python
Python 2.7.17 (default, Oct 19 2019, 23:36:22)
[GCC 9.2.1 20191008] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import dummyT; dy = dummyT.Yint(); print dy.twice(), dy.twice(2,-1.)
10 -2
确定:效果很好。但是,现在我需要“模板化”具有2个类型T和U的类:
>> more dummyTU.cpp
#include <string>
#include <boost/python.hpp>
#include <boost/preprocessor.hpp>
using namespace boost::python;
template<typename T, typename U>
class Z
{
public:
Z() {};
T twice(T x=5, U y=2.) {return (T)(x*y);};
};
#define SEVERAL_ARGS_AS_ONE_EXPAND(a,b) Z<a,b>::twice
#define SEVERAL_ARGS_AS_ONE_EXPAND_EXPAND(a,b) SEVERAL_ARGS_AS_ONE_EXPAND(a,b)
#define SEVERAL_ARGS_AS_ONE(a,b) SEVERAL_ARGS_AS_ONE_EXPAND_EXPAND(a,b)
#define ARGS int, float
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(Zintfloat_twice_overloads, SEVERAL_ARGS_AS_ONE(ARGS), 0, 2)
template<typename T, typename U, typename O>
void exportZ(std::string type)
{
class_<Z<T,U>>(type.c_str()).def("twice", &Z<T,U>::twice, O(args("x", "y")));
};
BOOST_PYTHON_MODULE(dummyTU)
{
exportZ<int, float, Zintfloat_twice_overloads>("Zintfloat");
}
>> make dummyTU
g++ -I /usr/include/python2.7 -o dummyTU.so -fPIC -shared dummyTU.cpp -lboost_python -lpython2.7
dummyTU.cpp:19:98: error: macro "SEVERAL_ARGS_AS_ONE" requires 2 arguments, but only 1 given
19 | BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(Zintfloat_twice_overloads, SEVERAL_ARGS_AS_ONE(ARGS), 0, 2)
此中断。
据我了解,“双宏扩展”技巧应该使“多个args成为一体”,但是,这似乎失败了。也无法使BOOST_PP_XXX正常工作。有没有办法使它工作?
解决方案:
>> more dummyTU.cpp
#include <string>
#include <boost/python.hpp>
using namespace boost::python;
template<typename T, typename U>
class Z
{
public:
Z() {};
T twice(T x=5, U y=2.) {return (T)(x*y);};
};
#define SEVERAL_ARGS_AS_ONE_EXPAND(a,b) Z<a,b>
#define SEVERAL_ARGS_AS_ONE_EXPAND_EXPAND(...) SEVERAL_ARGS_AS_ONE_EXPAND(__VA_ARGS__)
#define SEVERAL_ARGS_AS_ONE(...) SEVERAL_ARGS_AS_ONE_EXPAND_EXPAND(__VA_ARGS__)
#define N_ARGS() int,float
typedef SEVERAL_ARGS_AS_ONE(N_ARGS()) ZintfloatTD;
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(Zintfloat_twice_overloads, ZintfloatTD::twice, 0, 2)
template<typename T, typename U, typename O>
void exportZ(std::string type)
{
class_<Z<T,U>>(type.c_str()).def("twice", &Z<T,U>::twice, O(args("x", "y")));
};
BOOST_PYTHON_MODULE(dummyTU)
{
exportZ<int, float, Zintfloat_twice_overloads>("Zintfloat");
}
>> make dummyTU
g++ -I /usr/include/python2.7 -o dummyTU.so -fPIC -shared dummyTU.cpp -lboost_python -lpython2.7
>> python
Python 2.7.17 (default, Oct 19 2019, 23:36:22)
[GCC 9.2.1 20191008] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import dummyTU; dz = dummyTU.Zintfloat(); print dz.twice(), dz.twice(2,-1.)
10 -2