返回对自定义对象的引用时Boost.Python出错

时间:2012-07-14 23:23:07

标签: c++ boost boost-python

编辑:我注意到我的问题不够明确;我没有指定n0是Edge的属性。

我有两个类Nodes和Edges。 Edge是定义的(我省略了许多不感兴趣的方法和属性):

class Edge()
{
  Node& n0;
public:
  const Node& N0() const;
};

访问者编码如下:

Node const& Edge::N0() const
{
  return n0;
};

其中n0是Node()实例的私有引用。问题是,在尝试使用以下代码公开此函数时:

class_<Edge>("Edge", init<Node&,Node&>())
    .add_property("n0",&Edge::N0,return_internal_reference<>());

(类Node之前暴露) 我收到错误:

  

错误:无法创建指向引用成员'Edge :: n0'

的指针

我可以让访问者返回n0的副本,它可以正常工作(测试)。但是,如果n0非常重,我宁愿性能问题返回const引用而不是副本。

任何人都可以向我解释我在做什么有什么问题吗?我对C ++和Boost.Python很陌生,但对于呼叫策略还不太了解。

3 个答案:

答案 0 :(得分:3)

所以,我仍然不明白为什么我的原始程序或@ForEveR的解决方案不起作用,但我找到了一个解决方法,它给了我想要的东西。

首先,在定义边缘类的文件中,我定义了以下函数:

Node const& Edge_get_nodes(Edge& self)
{
   return self.N0(); 
};

我为包装器写道:

class_<Edge>("Edge", init<Node&,Node&>())
   .add_property("length",&Edge::GetLength)
   .def("GetNode",&Edge_get_nodes,return_value_policy<reference_existing_object>());

现在,当我在python中导入模块时,我可以让n0执行以下操作:

e1.GetNode()

这正是我想要的。谢谢你的帮助!

(如果有人能向我解释为什么它会这样,而不是其他方式,我很乐意知道!)

答案 1 :(得分:2)

2年后,如果您使用add_property,仍然可以通过boost::python::make_function执行此操作:

class_<Edge>("Edge", init<Node&,Node&>())
    .add_property(
        "n0", 
        make_function(&Edge::N0, return_value_policy<reference_existing_object>()));

答案 2 :(得分:0)

// property creation
    template <class Get>
    void add_property(char const* name, Get const& fget, char const* doc=0);
    template <class Get, class Set>
    void add_property(
        char const* name, Get const& fget, Set const& fset, char const* doc=0);

http://www.boost.org/doc/libs/1_50_0/libs/python/doc/v2/class.html#class_-spec

所以

class_<Edge>("Edge", init<Node&,Node&>())
    .add_property("n0",&Edge::N0, "get private edge");

应该有效。