boost/python/reference_existing_object.hpp

クラス

reference_existing_object クラス

struct reference_existing_object

reference_existing_object は、C++ オブジェクトへの参照かポインタを返すC++関数をラップするのに使用する ResultConverterGenerator のモデルである。ラップした関数を呼び出すとき、戻り値が参照する値はコピーされない。新しい Python オブジェクトは参照先へのポインタを持ち、対応する Python オブジェクトと少なくとも同じ長さの寿命となるような処置はなされない。よって、with_custodian_and_ward 等の CallPolicies モデルを利用した他の寿命管理無しで reference_existing_object を使用すると非常に危険となる可能性がある。このクラスは return_internal_reference の実装に使用されている。

reference_existing_object クラスの概要

namespace boost { namespace python
{
    struct reference_existing_object
    {
        template <class T> struct apply;
    };
}}

reference_existing_object クラスのメタ関数

template<class T>
struct apply
要件

ある U に対して TU&U*

typedef to_python_indirect<T, V> type

V は、ラップする関数の戻り値が参照する先への所有権のない U* ポインタを持つインスタンスホルダを構築する execute 静的関数を持つクラス。

C++ 側
#include <boost/python/module.hpp>
#include <boost/python/class.hpp>
#include <boost/python/reference_existing_object.hpp>
#include <boost/python/return_value_policy.hpp>
#include <utility>

// ラップするクラス群
struct Singleton
{
   Singleton() : x(0) {}

   int exchange(int n)  // x を設定し、古い値を返す
   {
        std::swap(n, x);
        return n;
   }

   int x;
};

Singleton& get_it()
{
   static Singleton just_one;
   return just_one;
}

// ラッパコード
using namespace boost::python;
BOOST_PYTHON_MODULE(singleton)
{
    def("get_it", get_it,
        return_value_policy<reference_existing_object>());

    class_<Singleton>("Singleton")
       .def("exchange", &Singleton::exchange)
       ;
}
Python 側
>>> import singleton
>>> s1 = singleton.get_it()
>>> s2 = singleton.get_it()
>>> id(s1) == id(s2)  # s1 と s2 は同じオブジェクトではないが
0
>>> s1.exchange(42)   # 同じ C++ の Singleton を参照する
0
>>> s2.exchange(99)
42