[C++-sig] boost.python iterators

Dirk Steenpass steenpaz at sdf-eu.org
Tue Aug 16 22:26:49 CEST 2005


On Tue, 16 Aug 2005 09:05:47 -0400, David Abrahams wrote:

> Dirk Steenpass <steenpaz at sdf-eu.org> writes:
> 
>> Yep, that is neat and works. Though the default_call_policies cannot be
>> used as the wrapped iterator returns by reference.
> 
> That is not a foregone conclusion, but it may be true in your case.

I try to be more precise: the default_call_policies will work
for wrapped iterators that return non-pointer types, char const*, and
PyObject* by value. Or putting it differently, functions that return
references (aka automatically dereferenced pointer types) are not accepted
by default_call_policies.

Thus the following snippet is not supposed to compile
(and does not do so):

//-------------------------------------------
// default_call_policies
#include <boost/python.hpp>

class Coo
{
public:
    Coo(int x): c_(x) {}
    int const& get_c() const { return c_; }

private:
    int c_;
};

using namespace boost::python;
BOOST_PYTHON_MODULE(coo)
{
    class_<Coo>("Coo", init<int>())

        // Fails because of bad call policy.
        .def("get_c", &Coo::get_c,
             default_call_policies())
        ;
}

int main(void)
{ return 0; }
//-------------------------------------------

I'm rather tenacious on the topic because the behavior of another call
policy, namely return_internal_reference, keeps confusing me; most
likely because I miss some important point about call policies in general.

The following snippet illustrates that return_internal_reference can be
used for a simple user defined type but not for the fundamental int. I am
probably making a fool of myself, but I do not see why this is so.

I am using boost-1.33.0.

As usual, looking for enlightenment,

dirk

//------------------------------------------
// return_internal_reference
#include <boost/python.hpp>

struct C
{
    C(int x): c_(x) {}
    int c_;
};

class B
{
public:
    B(int x) : b_(x), c_(x) {}

    int const& get_b() const { return b_; }
    C   const& get_c() const { return c_; }

private:
    int b_;
    C c_;
};

using namespace boost::python;
BOOST_PYTHON_MODULE(b)
{
    class_<B>("B", init<int>())

        // Fundamental type, cannot be returned
        // by reference this way.
        .def("get_b", &B::get_b,
             return_internal_reference<>())

        // User defined type: compiles fine.
        .def("get_c", &B::get_c,
             return_internal_reference<>())
        ;
}

int main(void)
{ return 0; }







More information about the Cplusplus-sig mailing list