[C++-sig] using function objects as getters/setters for the properties

Gennadiy Rozental rogeeff at gmail.com
Wed Feb 11 07:07:02 CET 2009


David Abrahams <dave <at> boostpro.com> writes:

> Frankly I'm not sure it's possible to use a function object in that way.
> Have you tried simply using the data member pointer without the wrapper?
> 
>      bp::class_< MyClass >( "MyClass", bp::no_init )
>          .add_property( "field", &MyClass::field )
> 
> ??


Whole point was that the above is not what I want I want the property to have
translated value.

I found one solution to my problem.

template<typename T>
bp::object
make_getter( MyClass T::* mem )
{
    // Unfortunately we have to resort to using function from details, 
    // since public interface is lacking
    return bp::detail::make_function_aux( Getter<T>( mem ), 
                                          bp::default_call_policies(), 
                                          boost::mpl::vector<bp::object,T>() );
}

and this seems to work fine. Ideally get_signature should be updated to work
with function objects properly. I am fine with extra typedefs I might be
required to make. Also make_function can use named template parameters in most
generic form.

similar way I was able to create setters:

template<typename T>
struct Setter {
    explicit Setter( MyClass T::* mem ) : m_member( mem ) {}

    void            operator()( T const& obj, bp::object const& val ) const
    {
        obj.*m_member = /* reverse conversion here */;
    }

    MyClass T::*   m_member;
};

template<typename T>
bp::object
make_setter( MyClass T::* mem )
{
    // Unfortunately we have to resort to using function from details, 
    // since public interface is lacking
    return bp::detail::make_function_aux( Setter<T>( mem ), 
                                          bp::default_call_policies(), 
                                          boost::mpl::vector<void,T,bp::object
const&>() );
}

And use it like this:

    bp::class_< A >( "A", bp::no_init )
        .add_property( "fld", make_getter( &A::fld ), make_setter( &A::fld ) )





More information about the Cplusplus-sig mailing list