Boost Python重写相等运算符

马克斯·希弗林(Max Shifrin)

我试图为通过boost python公开的类重写python相等运算符。

所以我的代码看起来像:

   class_<MyClass, boost::noncopyable, boost::shared_ptr<MyClass> >("MyClass", no_init)
    .def("foo", &MyClass::foo)                                    
     .
     .
     .
    .def("__eq__", &MyClass::operator==) 
    .def("__ne__", &MyClass::operator!=)

但是在python中,当我接受代表相同C ++对象的对象的2个实例,但它们来自不同的python对象时,它们永远不相等...

因此:

from myPackage import myClass

v1 = myClass.get("abc")
v2 = myClass.get("abc")
if v1 == v2:
   print "true"
else:
   print "false"

始终打印为假。(为简单起见,我从对象中省略了get函数定义)

有任何想法吗?

坦纳·桑斯伯里(Tanner Sansbury)

考虑编写一个C ++测试用例MyClass::operator==()以验证其实现。暴露运算符的Boost.Python代码是正确的。


这是一个示例,展示了将C ++类的比较运算符公开为相等和不相等的丰富比较方法:

#include <iostream>
#include <string>
#include <boost/make_shared.hpp>
#include <boost/python.hpp>
#include <boost/shared_ptr.hpp>

class foo
{
public:
  foo(const char* value) : value_(value) {}
  foo(const foo&) = delete;
  foo& operator=(const foo&) = delete;

  bool operator==(const foo& rhs) 
  {
    std::cout << "foo::operator==()" << std::endl;
    return value_ == rhs.value_;
  }

  bool operator!=(const foo& rhs)
  {
    std::cout << "foo::operator!=()" << std::endl;  
    return !(*this == rhs);
  }

  std::string get_value() const     { return value_;  }
  void set_value(std::string value) { value_ = value; }

private:
  std::string value_;
};

boost::shared_ptr<foo> make_foo(const char* value)
{
  return boost::make_shared<foo>(value);
}

BOOST_PYTHON_MODULE(example)
{
  namespace python = boost::python;
  python::class_<foo, boost::shared_ptr<foo>, boost::noncopyable>(
      "Foo", python::no_init)
    .def("__init__", python::make_constructor(&make_foo))
    .def("__eq__", &foo::operator==)
    .def("__ne__", &foo::operator!=)
    .add_property("value", &foo::get_value, &foo::set_value)
    ;
}

互动用法:

>>> import example
>>> foo1 = example.Foo("abc")
>>> foo2 = example.Foo("abc")
>>> foo3 = example.Foo("def")
>>> assert(foo1 == foo1)
foo::operator==()
>>> assert(foo1 == foo2)
foo::operator==()
>>> assert(foo1 is not foo2)
>>> assert(foo1 != foo3)
foo::operator!=()
foo::operator==()
>>> foo1.value = foo3.value
>>> assert(foo1 != foo2)
foo::operator!=()
foo::operator==()
>>> assert(foo1 == foo3)
foo::operator==()

从上面的输出中可以看到,C ++比较运算符是从Python调用的。


在示例中,make_foo()工厂函数创建唯一的C ++foo实例。因此,我选择通过包装make_foo()为构造函数并将其公开为方法来将工厂方法的实现细节隐藏到Python中__init__如此处所示,如果通过静态方法创建对象,仍然可以检查是否相等。另一方面,如果静态工厂方法get()可以将句柄返回给现有foo实例,则可以期望相等和身份比较都可以在FooPython对象上进行(例如,assert(Foo.get("abc") is Foo.get("abc"))要返回对同一Python对象的引用,则需要管理相关的PyObject

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

使用带有boost :: optional的相等运算符

如何实现Boost.Hana结构的相等比较运算符?

如何定义boost :: any运算符==

boost.Geometry运算符

重写Python的“ in”运算符?

使用动态数组和delete运算符的boost :: python内存错误

使用Boost Python,我可以包装C ++重载运算符“ + =”,“-=”,“ * =”,但不能包装“ / =”?

如何使用“ =”运算符复制boost python列表或他的引用

boost :: iterator_facade运算符->()无法编译

Boost.Spirit:运算符“%=”和“ =”之间的区别

C ++运算符[]通过模板访问boost :: variant的重载

如何更改boost :: variant运算符的行为<

Boost.Spirit X3替代运算符

在Boost.Log中正确重载运算符<<

Boost.Log忽略重载的流插入运算符

模板转换运算符和 boost::any 或 std::any

了解Boost.Spirit中的列表运算符(%)

boost :: unit_test ::数据运算符^?

使用boost :: variant C ++隐式运算符重载

boost :: chrono :: duration的运算符>>支持哪些格式?

永远不会调用重写的相等运算符

在Python中重写not运算符

Python运算符:数学优先级比较运算符与相等运算符

Javascript相等运算符

是!=运算符的重写候选

为什么我们在包含boost :: none的boost :: optional <T>上使用间接/取消引用(*)运算符?

打印Boost Boost Python对象

如何包装(组成)Boost Hana映射并访问括号运算符(operator [])?

什么阻止了 Boost.Format 表单使用我的流运算符重载可选的 int?