这与this question,类似,但它从来没有得到任何解决方案,而且我至少有一个解决方法,因为它不够优雅。
我正在尝试包装一个模板化的类Point<_T,__Scale>
,其中_T=int,float...
和__Scale
是一个int。现在,编译器将为使用的每个模板值生成一个单独的类,但这些类不以任何方式相关。但是,这些类共享所有方法,主要是!=<>*&/|
的运算符重载和getter。
在Cython中,我能够包装Point<_T,__Scale>
的唯一方法是为每个变体提供一个cdef类。它可以工作,但会产生大量的复制粘贴代码。我想知道是否有办法在这些模板类包装器之间共享代码。请注意,我遵循教程中描述的包装的cython方法,其中包装类将*thisptr
保存到它正在包装的c对象。
// c++ header
template<_T,__Scale>
class Point
{
Point(_T _x, _T _y) : x(_x), y(_y) {};
// copy constructor
template<typename _NT> Point(const Point<_NT, __Scale> &pt) : x( (_T)pt.x ), y( (_T)pt.y ) {};
_t x, y;
bool operator == (const Point<_T,__Scale> &pos) const
bool operator != (const Point<_T,__Scale> &pos) const
// and many more operators
}
typedef Point<int,1> PointA
typedef Point<int,8> PointB
... //additional typedefs
# cython interface with c++ (not shown: cdef extern from ...)
cdef cppclass Point[_T,__Scale]:
Point(_T _x, _T _y)
Point[_NT] Point(const Point[_NT,0] &pt)
_T x
_T y
bint operator == (const Point[_T,__Scale] &pos) const
bint operator != (const Point[_T,__Scale] &pos) const
# cython wrapper to interface with python (this is where it gets messy)
cdef class pyPointA:
cdef PointA* thisptr
def __cinit__(self, int x, int y):
self.thisptr = new PointA(x,y)
# everything in this class below this line is copied
def x(self, setX = None):
if(setX is None):
return self.thisptr.x
else:
self.thisptr.x = setX
def y(self, setY = None):
if(setY is None):
return self.thisptr.y
else:
self.thisptr.y = setY
# and many more operators
cdef class pyPointB
cdef PointB* thisptr
def __cinit__(self, int x, int y):
self.thisptr = new PointB(x,y)
# everything in this class below this line is copied
def x(self, setX = None):
if(setX is None):
return self.thisptr.x
else:
self.thisptr.x = setX
def y(self, setY = None):
if(setY is None):
return self.thisptr.y
else:
self.thisptr.y = setY
# and many more operators
...
#continue for additional point types
以下是我的尝试:
*thisptr
存储为*void
。如何处理铸造?thisptr
检索它来封装getPtr()
,但仍然被强制转换为单个返回类型。不能声明为Python函数,因为c指针不能包装在python对象中。getPtr()
方法为每个要调用的方法返回正确的getter,以获取指针。不幸的是,只有c函数可以返回指针,并且无法返回它们:编译器抱怨'找不到'。getPtr()
方法返回getter函数的字符串名称,然后我们可以使用getattr()
来回忆。但是使用getattr()
无法在Python中找到cdef方法。答案 0 :(得分:1)
这方面的困难在于模板需要在C编译时实例化......当然在C ++中,各种模板实例化没有共同的“超类”。
通常我建议在这种情况下使用模板引擎(如jinja2)来生成您感兴趣的所有类的排列。