3

編集:私の質問が十分に明確ではないことに気付きました。n0 が Edge の属性であるとは指定していませんでした。

ノードとエッジの 2 つのクラスがあります。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' へのポインタを作成できません</p>

アクセサーが n0 のコピーを返すようにすることができ、正常に動作します (テスト済み)。ただし、 n0 が非常に重い場合は、パフォーマンスの問題から、コピーではなく const 参照を返すことをお勧めします。

私がしていることの何が悪いのか、誰かが私に説明できますか? 私は C++ と Boost.Python にかなり慣れていないため、呼び出しポリシーについてまだあまり理解していません。

4

3 に答える 3

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()

それはまさに私が欲しかったものです。ご協力いただきありがとうございます!

(誰かがなぜそれがこのように機能し、他の方法では機能しないのかを私に説明できれば、私は喜んで知っています!)

于 2012-07-15T22:04:52.643 に答える
-1
// 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");

動作するはずです。

于 2012-07-15T08:56:06.963 に答える