2012-07-14 91 views
3

編輯:我注意到我的問題不夠清晰;我沒有指定n0是Edge的一個屬性。Boost.Python在返回對自定義對象的引用時出錯

我有兩個類節點和邊緣。邊緣被定義(我省略了很多的方法和屬性,這裏不感興趣):

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

的訪問編碼如下:

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

這裏n0是一個節點一個私有引用( )實例。問題是,在試圖用下面的代碼公開此功能:

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

(類節點是正確的曝光前) 我得到的錯誤:

error: cannot create pointer to reference member ‘Edge::n0’

我可以讓訪問者返回n0的副本,它會正常工作(測試)。但是,如果n0真的很重,我寧願爲性能問題返回一個const引用而不是副本。

任何人都可以向我解釋我在做什麼錯?我對C++和Boost.Python相當陌生,並承認對呼叫策略還不太瞭解。

回答

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做以下操作:

​​

這正是我想要的。謝謝你的幫助!

(如果有人可以給我,爲什麼它是這樣工作的,並解釋不是其他的方式,我很樂意知道!)

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"); 

應該作品。

+0

非常感謝您的回答!編譯器停下來侮辱了我幾行。但是,我現在有一個錯誤說「錯誤:不能創建指向參考成員'Edge :: n0'的指針」。 但是,由於我返回一個const引用(因此無法修改該值),這是怎麼回事?在那個特定的例子中,我可以簡單地返回一個n0的副本,但是如果我想要返回一個非常重的對象呢? – scities 2012-07-15 10:42:38

+0

如何使用def(「n0」,&Edge :: N0,return_internal_reference <>)?或add_propery(「n0」,make_getter(&Edge :: N0,return_internal_reference <>)),「edge getter」)或者簡單地使用add_property(「n0」,make_getter(&Edge :: N0),「邊緣吸氣劑」)? – ForEveR 2012-07-15 14:30:10

+0

感謝您的幫助!我之前曾嘗試過您提出的第一個解決方案,但它不起作用,原因與上述相同(抱怨n0是私有的,然後「無法創建指向參考成員'Edge :: n0'的指針」)。你的其他命題導致了完全相同的錯誤。 – scities 2012-07-15 15:09:26

1

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>())); 
相關問題