title: boost python: tie lifetime of argument to returned value using return_internal_reference
body: <p>I begin learning to use boost python and have a rookie question.</p>
  
  <p>I would like to write a function that can tie the lifetime of its argument to its results, such that when I call <code>r = func(a)</code>, the argument <code>a</code> will never be destroyed if I still have a reference of <code>r</code>. The documentation suggests using <code>return_internal_reference</code> call policy for this type of request. But does this require <code>r</code> to be an internal reference of <code>a</code>, as the name suggested?</p>
  
  <p>In the (over-simplified) example below, suppose I want to tie the lifetime of input array <code>a</code> with the generated lambda function, which is not an internal reference of input <code>a</code>.</p>
  
  <pre><code>#include &lt;functional&gt;
  #include &lt;boost/python.hpp&gt;
  #include &lt;boost/python/return_internal_reference.hpp&gt;
  
  using namespace std;
  using namespace boost::python;
  
  function&lt;float(int)&gt; func(const float* a) {
    return [=](int n) { return a[n]; };
  }
  
  BOOST_PYTHON_MODULE(test) {
    def("func", func, return_internal_reference&lt;1&gt;());
  }
  </code></pre>
  
  <p>I hope to be able to do the following in python:</p>
  
  <pre><code>f = func(a)   # 'a' can be a temporary variable, say returned by another function
  f(5)          # but 'a' should not be destroyed at this step, 
                # because its lifetime is tied to 'f'
  </code></pre>
  
  <p>When I tried to compile the code above, I got a wall of errors listed below, but if I remove the <code>return_internal_reference&lt;1&gt;()</code> call policy, the code compiles successfully.</p>
  
  <p>I am pretty sure I used this call policy wrong, but am not sure how to make it right. Any pointer will be highly appreciated. Thanks a lot!</p>
  
  <pre><code>$ g++ -std=c++11 -shared Test.cc -I/opt/local/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7 -L/opt/local/lib -lboost_python-mt -lpython2.7 -o test.so
  In file included from /opt/local/include/boost/preprocessor/iteration/detail/iter/forward1.hpp:52:0,
                   from /opt/local/include/boost/python/detail/invoke.hpp:63,
                   from /opt/local/include/boost/python/detail/caller.hpp:16,
                   from /opt/local/include/boost/python/object/function_handle.hpp:8,
                   from /opt/local/include/boost/python/converter/arg_to_python.hpp:19,
                   from /opt/local/include/boost/python/call.hpp:15,
                   from /opt/local/include/boost/python/object_core.hpp:14,
                   from /opt/local/include/boost/python/args.hpp:25,
                   from /opt/local/include/boost/python.hpp:11,
                   from Test.cc:2:
  /opt/local/include/boost/python/detail/invoke.hpp: In instantiation of 'PyObject* boost::python::detail::invoke(boost::python::detail::invoke_tag_&lt;false, false&gt;, const RC&amp;, F&amp;, AC0&amp;) [with RC = boost::python::detail::reference_existing_object_requires_a_pointer_or_reference_return_type&lt;std::function&lt;float(int)&gt; &gt;; F = std::function&lt;float(int)&gt; (*)(const float*); AC0 = boost::python::arg_from_python&lt;const float*&gt;; PyObject = _object]':
  /opt/local/include/boost/python/detail/caller.hpp:223:13:   required from 'PyObject* boost::python::detail::caller_arity&lt;1u&gt;::impl&lt;F, Policies, Sig&gt;::operator()(PyObject*, PyObject*) [with F = std::function&lt;float(int)&gt; (*)(const float*); Policies = boost::python::return_internal_reference&lt;&gt;; Sig = boost::mpl::vector2&lt;std::function&lt;float(int)&gt;, const float*&gt;; PyObject = _object]'
  /opt/local/include/boost/python/object/py_function.hpp:38:33:   required from 'PyObject* boost::python::objects::caller_py_function_impl&lt;Caller&gt;::operator()(PyObject*, PyObject*) [with Caller = boost::python::detail::caller&lt;std::function&lt;float(int)&gt; (*)(const float*), boost::python::return_internal_reference&lt;&gt;, boost::mpl::vector2&lt;std::function&lt;float(int)&gt;, const float*&gt; &gt;; PyObject = _object]'
  Test.cc:14:1:   required from here
  /opt/local/include/boost/python/detail/invoke.hpp:75:82: error: no match for call to '(const boost::python::detail::reference_existing_object_requires_a_pointer_or_reference_return_type&lt;std::function&lt;float(int)&gt; &gt;) (std::function&lt;float(int)&gt;)'
       return rc(f( BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, ac, () BOOST_PP_INTERCEPT) ));
                                                                                    ^
  In file included from /opt/local/include/boost/python/object/function_handle.hpp:8:0,
                   from /opt/local/include/boost/python/converter/arg_to_python.hpp:19,
                   from /opt/local/include/boost/python/call.hpp:15,
                   from /opt/local/include/boost/python/object_core.hpp:14,
                   from /opt/local/include/boost/python/args.hpp:25,
                   from /opt/local/include/boost/python.hpp:11,
                   from Test.cc:2:
  /opt/local/include/boost/python/detail/caller.hpp: In instantiation of 'static const PyTypeObject* boost::python::detail::converter_target_type&lt;ResultConverter&gt;::get_pytype() [with ResultConverter = boost::python::detail::reference_existing_object_requires_a_pointer_or_reference_return_type&lt;std::function&lt;float(int)&gt; &gt;; PyTypeObject = _typeobject]':
  /opt/local/include/boost/python/detail/caller.hpp:240:19:   required from 'static boost::python::detail::py_func_sig_info boost::python::detail::caller_arity&lt;1u&gt;::impl&lt;F, Policies, Sig&gt;::signature() [with F = std::function&lt;float(int)&gt; (*)(const float*); Policies = boost::python::return_internal_reference&lt;&gt;; Sig = boost::mpl::vector2&lt;std::function&lt;float(int)&gt;, const float*&gt;]'
  /opt/local/include/boost/python/object/py_function.hpp:48:35:   required from 'boost::python::detail::py_func_sig_info boost::python::objects::caller_py_function_impl&lt;Caller&gt;::signature() const [with Caller = boost::python::detail::caller&lt;std::function&lt;float(int)&gt; (*)(const float*), boost::python::return_internal_reference&lt;&gt;, boost::mpl::vector2&lt;std::function&lt;float(int)&gt;, const float*&gt; &gt;]'
  Test.cc:14:1:   required from here
  /opt/local/include/boost/python/detail/caller.hpp:102:109: error: 'struct boost::python::detail::reference_existing_object_requires_a_pointer_or_reference_return_type&lt;std::function&lt;float(int)&gt; &gt;' has no member named 'get_pytype'
           return create_result_converter((PyObject*)0, (ResultConverter *)0, (ResultConverter *)0).get_pytype();
                                                                                                               ^
  </code></pre>