BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS用于重载多类型模板:具有多个arg的宏作为一个宏

问题描述 投票:0回答:1

使用常规类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正常工作。有没有办法使它工作?

macros boost-python
1个回答
0
投票

解决方案:

>> 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
© www.soinside.com 2019 - 2024. All rights reserved.