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

C++ 返回对自定义对象的引用时Boost.Python出错,c++,boost,boost-python,C++,Boost,Boost Python,编辑:我注意到我的问题不够清楚;我没有指定n0是Edge的属性 我有两个类,节点和边。定义了Edge(我省略了许多不感兴趣的方法和属性): 存取器的编码如下: Node const& Edge::N0() const { return n0; }; 其中n0是对Node()实例的私有引用。问题是,在尝试使用以下代码公开此函数时: class_<Edge>("Edge", init<Node&,Node&>()) .add_proper

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

我有两个类,节点和边。定义了Edge(我省略了许多不感兴趣的方法和属性):

存取器的编码如下:

Node const& Edge::N0() const
{
  return n0;
};
其中n0是对Node()实例的私有引用。问题是,在尝试使用以下代码公开此函数时:

class_<Edge>("Edge", init<Node&,Node&>())
    .add_property("n0",&Edge::N0,return_internal_reference<>());
类(“边缘”,init())
.add_属性(“n0”,&Edge::n0,返回_internal_reference());
(类节点就在前面公开) 我得到一个错误:

错误:无法创建指向引用成员“Edge::n0”的指针

我可以让访问器返回n0的一个副本,它可以正常工作(经过测试)。然而,如果n0真的很重,我更愿意在性能问题上返回常量引用而不是副本

谁能向我解释一下我现在做的有什么不对吗?我对C++和Boosi.Python非常陌生,并且还不太了解调用策略。

<代码> /属性创建
// 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);
模板 void add_属性(char const*name,Get const&fget,char const*doc=0); 模板 void add_属性( char const*name,Get const&fget,Set const&fset,char const*doc=0);

所以

类(“边缘”,init())
.add_属性(“n0”和&Edge::n0,“获取私有边缘”);

应该有效。

所以,我仍然不明白为什么我的原始程序或@ForEveR的解决方案不起作用,但我确实找到了一个解决方案,它满足了我的需要

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

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>());
这正是我想要的。谢谢你的帮助


(如果有人能向我解释为什么它是这样工作的,而不是相反,我很高兴知道!)

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

class_<Edge>("Edge", init<Node&,Node&>())
    .add_property(
        "n0", 
        make_function(&Edge::N0, return_value_policy<reference_existing_object>()));
类(“边缘”,init())
.add_属性(
“n0”,
make_函数(&Edge::N0,返回_值_策略());

非常感谢您的回答!编译器停下来侮辱了我好几行。但是,我现在有一个错误,错误是“error:cannotcreatepointtoreferencemember'Edge::n0'”。但是,既然我返回了对常量的引用(因此无法修改该值),那么这又是一个什么问题呢?在那个特定的例子中,我可以简单地返回n0的一个副本,但是如果我想返回一个非常重的对象呢?那么使用def(“n0”,&Edge::n0,return\u internal\u reference)或者add\u property(“n0”,make\u getter(&Edge::n0,return\u internal\u reference)),“Edge getter”)或者简单地使用add\u属性(“n0”,make\u getter(&Edge::n0),“Edge getter”)怎么样?谢谢你的帮助!我以前尝试过您提出的第一个解决方案,但由于与上面相同的原因,它不起作用(抱怨n0是私有的,然后“无法创建指向引用成员'Edge::n0'的指针”)。你的其他主张导致了完全相同的错误。好吧,我认为这是不真实的。没有可返回成员引用/指针的变量。Mb您可以使用一些包装器或其他东西,但是没有任何变体可以在没有魔法的情况下使用它。是的,我尝试过解决这个问题,但最终成功了!我不确定我是否需要通过引用返回,但我认为如果我需要访问作为类属性的大对象(比如有一百万个节点的大邻接列表),那么返回引用要比返回值快得多,不是吗?实际上,当python和引用一起工作时,它是如何工作的?它是否复制了对象?如果您有任何可以向我解释这一点的链接,我将不胜感激。无论如何,谢谢你的帮助!
class_<Edge>("Edge", init<Node&,Node&>())
   .add_property("length",&Edge::GetLength)
   .def("GetNode",&Edge_get_nodes,return_value_policy<reference_existing_object>());
e1.GetNode()
class_<Edge>("Edge", init<Node&,Node&>())
    .add_property(
        "n0", 
        make_function(&Edge::N0, return_value_policy<reference_existing_object>()));