gpt4 book ai didi

c++ - 在 Cython 中包装 C++ friend 非成员运算符

转载 作者:搜寻专家 更新时间:2023-10-31 02:08:06 26 4
gpt4 key购买 nike

我是 c++ 和 cython 的新手,对在 Cython 中包装 C++ friend 非成员运算符感到困惑。这是一个我试图包装但失败的小例子。非常感谢

现在,如何在 pyx 文件中声明友元运算符

all files can be found here, makefile for test -

矩形.h

 namespace shapes {
class Rectangle {
public:
int x0, y0, x1, y1;
Rectangle(int x0=0, int y0=0, int x1=0, int y1=0);
~Rectangle();
int getLength();
Rectangle operator+(const Rectangle& target);
friend Rectangle operator-(const Rectangle & left, const Rectangle & right);
};
}

矩形.cpp

#include "Rectangle.h"

using namespace shapes;

Rectangle::Rectangle(int X0, int Y0, int X1, int Y1) {
x0 = X0;
y0 = Y0;
x1 = X1;
y1 = Y1;
}


int Rectangle::getLength() {
return (x1 - x0);
}

Rectangle::~Rectangle()
{

}

Rectangle Rectangle::operator+(const Rectangle & target) {
return Rectangle(x0+target.x0, y0+target.y0,x1+target.x1,y1+target.y1);
}

Rectangle operator-(const Rectangle & left,const Rectangle & right) {
return Rectangle(left.x0 - right.x0,
left.y0-right.y0,
left.x1-right.x1,
left.y1-right.y1);
}

pyx文件

from libcpp.vector cimport vector
from cython.operator cimport dereference as deref

# c++ interface to cython
cdef extern from "Rectangle.h" namespace "shapes":
cdef cppclass Rectangle:
Rectangle() except +
Rectangle(int, int, int, int) except +
int x0, y0, x1, y1
int getLength()
Rectangle opadd "operator+"(Rectangle right)
Rectangle opsub "operator-" (Rectangle right)
# Rectangle opsub "operator-"(Rectangle left ,Rectangle right)

# cdef extern from "Rectangle.h" namespace "shapes":
# cdef Rectangle opsub "operator-"(Rectangle left ,Rectangle right)

# creating a cython wrapper class
cdef class PyRectangle:
cdef Rectangle *thisptr # hold a C++ instance which we're wrapping
def __cinit__(self, int x0=0, int y0=0, int x1=0, int y1=0):
self.thisptr = new Rectangle(x0, y0, x1, y1)
def __dealloc__(self):
del self.thisptr
def getLength(self):
return self.thisptr.getLength()
def __add__(PyRectangle left,PyRectangle right):
cdef Rectangle rect = left.thisptr.opadd(right.thisptr[0])
cdef PyRectangle sum = PyRectangle(rect.x0,rect.y0,rect.x1,rect.y1)
return sum
def __sub__(PyRectangle left,PyRectangle right):
cdef Rectangle rect = left.thisptr.opsub(right.thisptr[0])
# cdef Rectangle rect = opsub(left.thisptr[0],right.thisptr[0])
cdef PyRectangle sub = PyRectangle(rect.x0,rect.y0,rect.x1,rect.y1)
return sub
def __repr__(self):
return "PyRectangle[%s,%s,%s,%s]" % (
self.thisptr.x0,
self.thisptr.y0,
self.thisptr.x1,
self.thisptr.y1)

我尝试过一些方法,比如

cdef extern from "Rectangle.h" namespace "shapes":
cdef Rectangle opsub "operator-"(Rectangle left ,Rectangle right)

或者假装它是 cppclass 声明中的成员定义运算符

Rectangle opsub "operator-" (Rectangle right)

如图所示,我两种方式都编译失败

error: no member named 'operator-' in 'shapes::Rectangle'

最佳答案

抱歉,我在 Rectangle.cpp 中发现了一个大错误。 operator-的定义需要加上命名空间前缀

    Rectangle shapes::operator-(const Rectangle & left,const Rectangle & right) {
return Rectangle(left.x0 - right.x0,
left.y0-right.y0,
left.x1-right.x1,
left.y1-right.y1);
}

并且rect.pyx可以根据DavidW的提示修改为直接调用operator。

    # c++ interface to cython
cdef extern from "Rectangle.h" namespace "shapes":
cdef cppclass Rectangle:
Rectangle() except +
Rectangle(int, int, int, int) except +
int x0, y0, x1, y1
int getLength()
Rectangle operator+(Rectangle right)
Rectangle operator-(Rectangle right)

#### nonmember operator can also work :
# cdef extern from "Rectangle.h" namespace "shapes":
# cdef Rectangle operator-(Rectangle left ,Rectangle right)

# creating a cython wrapper class
cdef class PyRectangle:
cdef Rectangle *thisptr # hold a C++ instance which we're wrapping
def __cinit__(self, int x0=0, int y0=0, int x1=0, int y1=0):
self.thisptr = new Rectangle(x0, y0, x1, y1)
def __dealloc__(self):
del self.thisptr
def getLength(self):
return self.thisptr.getLength()
def __add__(PyRectangle left,PyRectangle right):
cdef Rectangle rect = left.thisptr[0] + right.thisptr[0]
cdef PyRectangle sum = PyRectangle(rect.x0,rect.y0,rect.x1,rect.y1)
return sum
def __sub__(PyRectangle left,PyRectangle right):
cdef Rectangle rect = left.thisptr[0] - right.thisptr[0]
# cdef Rectangle rect = opsub(left.thisptr[0],right.thisptr[0])
cdef PyRectangle sub = PyRectangle(rect.x0,rect.y0,rect.x1,rect.y1)
return sub

关于c++ - 在 Cython 中包装 C++ friend 非成员运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47938326/

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