boost/python/return_internal_reference.hpp

はじめに

return_internal_reference のインスタンスは、自由関数かメンバ関数の引数またはメンバ関数の対象が内部的に保持するオブジェクトへのポインタおよび参照を参照先のコピーを作成することなく安全に返すことを可能とする CallPolicies モデルである。第 1 テンプレート引数の既定値は、内包するオブジェクトがラップするメンバ関数の対象(*this)となるよくある場合を処理する。

クラス

return_internal_reference クラステンプレート

template<std::size_t owner_arg = 1, class Base = default_call_policies>
struct return_internal_reference : Base
テンプレートパラメータ
  • owner_arg --

    返す参照かポインタ先のオブジェクトを含む引数の添字。ラップするのがメンバ関数の場合、引数 1 は対象オブジェクト(*this)である。1

    対象の Python オブジェクト型が弱い参照をサポートしない場合、ラップする関数を呼び出すと Python の TypeError 例外を送出する。

    要件

    std::size_t 型の正のコンパイル時定数。

    既定

    1

  • Base --

    ポリシーの合成に使用。提供する result_converterreturn_internal_reference によりオーバーライドされるが、その precall および postcall ポリシーは CallPolicies の項に示すとおり合成される。

    要件

    CallPolicies のモデルである

    既定

    default_call_policies

return_internal_reference クラステンプレートの概要

namespace boost { namespace python
{
   template <std::size_t owner_arg = 1, class Base = default_call_policies>
   struct return_internal_reference : Base
   {
      static PyObject* postcall(PyObject*, PyObject* result);
      typedef reference_existing_object result_converter;
   };
}}

return_internal_reference クラスの静的関数

PyObject *postcall(PyObject *args, PyObject *result)
要件

PyTuple_Check(args) != 0

戻り値

with_custodian_and_ward_postcall::postcall(args, result)

C++ のモジュール定義
#include <boost/python/module.hpp>
#include <boost/python/class.hpp>
#include <boost/python/return_internal_reference.hpp>

class Bar
{
 public:
   Bar(int x) : x(x) {}
   int get_x() const { return x; }
   void set_x(int x) { this->x = x; }
 private:
   int x;
};

class Foo
{
 public:
   Foo(int x) : b(x) {}

   // 内部的な参照を返す
   Bar const& get_bar() const { return b; }

 private:
   Bar b;
};

using namespace boost::python;
BOOST_PYTHON_MODULE(internal_refs)
{
   class_<Bar>("Bar", init<int>())
      .def("get_x", &Bar::get_x)
      .def("set_x", &Bar::set_x)
      ;

   class_<Foo>("Foo", init<int>())
      .def("get_bar", &Foo::get_bar
          , return_internal_reference<>())
      ;
}
Python のコード
>>> from internal_refs import *
>>> f = Foo(3)
>>> b1 = f.get_bar()
>>> b2 = f.get_bar()
>>> b1.get_x()
3
>>> b2.get_x()
3
>>> b1.set_x(42)
>>> b2.get_x()
42
1

訳注 owner_arg テンプレート引数に 0 や引数列の範囲を超える値を指定することはできません。