Pybind11 - 如何包装重载的赋值运算符?

4
我将使用pybind11将C++函数暴露给Python接口。我想包装重载的赋值运算符,但不知道如何做。文档和提供的示例并没有真正涵盖它,至少从我看到的来说。以下是我尝试实现的简化版本:
class Num{
  public:
    Num(const double& num) : m_val(num), m_type(Num::Type::e_none){}

    Num& operator=(const double& rhs){m_val = rhs;}

  private:
    double m_val;
};

这里是封装代码:

PYBIND11_MODULE(demo, m){
    py::class_<Num>(m, "Num")
        .def(py::init<const double&>())
        // Overloaded assignment operator binding ?
        ;
}

我的主要关注点是在将 Num 分配给浮点数时保留 Num 的数据类型。例如:

>>> m = Num(4.5)
>>> type(m)
<class 'demo.Num'>
>>> m = 5.5
>>> type(m)
<class 'float'>

这是我第一次使用C++扩展和绑定,所以如果您能提供任何建议,那将是很好的!


1
无法完成(好吧,你可以拦截全局字典__setitem__,但那是一个可怕的黑客和非常脆弱的方法)。问题在于Python使用引用赋值,因此没有赋值运算符可以覆盖。具体来说:第二个赋值会丢弃对Num的旧引用,然后重新分配给5.5。在任何时候都没有涉及到Num的任何方法。另一种选择是,如果所有的Num实例都存在于某个类或模块中,那么您可以覆盖该模块/类的__setitem__ - Wim Lavrijsen
啊,我明白了。所以Python创建了一个全新的本地bool对象,名为“m”的指针,而不是先前创建的Num对象。我现在对于搞乱任何dunder函数并不感兴趣,但这确实帮了很多忙。谢谢! - adriyens
2个回答

1

这仅适用于 Num& operator=(const Num&) 函数定义,因此无法处理双重赋值。 - themadmax
你可以这样做:.def("assign", py::overload_cast<double>&Num::operator=);。前提是你有一个接受double类型的赋值运算符。或者你可以这样做:.def("assign", [](double value, Num& self){self = Num(value)}); - plfoley

0

我没有足够的声望来评论Voya的回答,但是plfoley的回答中使用“py :: overload_cast”的语法是不正确的。应该是.def("assign", py::overload_cast<const double&>(&Num::operator=));


这并没有回答问题。一旦您拥有足够的声望,您将能够评论任何帖子;相反,提供不需要询问者澄清的答案。- 来自审核 - Woody1193

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接