在 cython 中为 cpp 使用访问器语法 类

Use accessor syntax in cython for cpp classes

如果我有一个class在C++中定义如下

class sample
{
private:
    int data;
public:
    sample()
    {
        data=0;
    }

    int get_data()
    {
        return data;
    }

    void set_data(int data)
    {
        this->data = data;
    }
};

我想使用以下方法将其暴露给 cython 代码:

cdef extern from "sample.cpp":
    cdef cppclass sample:
        sample() except +
        int get_data()
        void set_data(int n)

有没有办法在 class 中公开 getter 和 setter,然后可以使用以下语法在 cython 中使用它们:

a = obj.data

而不是

a = obj.get_data()

我知道可以通过在 cython 定义的 class 中包装 class 来做到这一点,但我想避免这种开销。

可能是我要求太多了

免责声明:我不了解 cython,所以我不能说以下是否适用于 cython。但是,我的策略是通过 C++ 代码中已有的 s.data 实现访问,以保持绑定简洁明了。

C++ 没有属性,但可以模拟它们:

#include <iostream>

template <typename T,typename M,M (T::*getter)(),void (T::*setter)(M)>
struct Attribute {
    T* parent;
    Attribute(T* parent) : parent(parent){}
    operator M() const {
        return (parent->*getter)();
    }
    void operator=(const M& m){
        (parent->*setter)(m);
    }

};

class sample
{
private:
    int data_;
public:

    sample()
    {
        data_=0;
    }    

    int get_data()
    {
        return data_;
    }

    void set_data(int data_)
    {
        this->data_ = data_;
    }
    Attribute<sample,int,&sample::get_data,&sample::set_data> data{this};
};

int main() {
    sample s;
    s.data = 42;
    std::cout << s.data;
}

输出为 42。请注意,我必须为 setter 假设一个 int 参数。要启用 const int& 还需要更多。

使用上面@idclev 463035818 接受的回复中示例 c++ class 的定义,为方便起见复制到这里:

#include <iostream>

template <typename T,typename M,M (T::*getter)(),void (T::*setter)(M)>
struct Attribute {
    T* parent;
    Attribute(T* parent) : parent(parent){}
    operator M() const {
        return (parent->*getter)();
    }
    void operator=(const M& m){
        (parent->*setter)(m);
    }

};

class sample
{
private:
    int data_;
public:

    sample()
    {
        data_=0;
    }    

    int get_data()
    {
        return data_;
    }

    void set_data(int data_)
    {
        this->data_ = data_;
    }
    Attribute<sample,int,&sample::get_data,&sample::set_data> data{this};
};

我测试了在 cython 中用平面 public 属性 声明 C++ class,并且......它有效!这样就可以了。

cdef extern from "sample.cpp":
    cdef cppclass sample:
        sample() except +
        int data

测试并检测示例中的访问器表明访问器被正确调用。

非常感谢大家!那是非常有帮助。