[C++-sig] Re: How to expose virtual function with default arguments in boost.python ?

Baptiste Lepilleur gaiacrtn at free.fr
Sun Dec 5 12:30:55 CET 2004


----- Original Message ----- 
From: "David Abrahams" <dave at boost-consulting.com>
To: <c++-sig at python.org>
Sent: Sunday, December 05, 2004 12:18 AM
Subject: [C++-sig] Re: How to expose virtual function with default arguments
in boost.python ?


> Baptiste Lepilleur wrote:
> [...]
>
> Right.  The problem here is that all the overloads for handling
> default arguments take a first argument of
>
>     py::VirtualNonCopyable_Wrapper {lvalue}
>
> (because they are member functions of VirtualNonCopyable_Wrapper)
> but the object you're creating in C++ is only of type
>
>    VirtualNonCopyable {lvalue}
>
> You can see most of this in the overload set described in the error
> message below, if you look carefully (using an initial type
> other than std::string would make it clearer).

I though it might be something along those lines, but I was confused by the
following things:
- the type dumped on the overloading error message is always the C++ type,
even if the object is actually the wrapper
- the wrapper overload are displayed even though they are not taken in
account in the overload resolution.

Not a major issue, but somewhat confusing...

> So one way to make it work is to add some functions that can be
> called for VirtualNonCopyable objects:
>
>    void set_2(VirtualNonCopyable& self, std::string s, int p1)
>    { self.set(s,p1); }
>
>    void set_1(VirtualNonCopyable&& self, std::string s)
>    { self.set(s); }
>
> And before any of the other defs (so if the object is actually a
> VirtualNonCopyable_Wrapper the other overloads will take
> priority), but in any order, you do:
>
>       .def("set", set_1)
>       .def("set", set_2)

This works great. It basically replace the default_set_1/2 binding, right ?

> Alternatively, you should be able to avoid defining any helper
> functions this way:
>
>       .def(
>           "set"
>         , make_function(
>               &VirtualNonCopyable::set
>             , mpl::vector<void,std::string,int,int>())
>       )
>       .def(
>           "set"
>         , make_function(
>               &VirtualNonCopyable::set
>             , mpl::vector<void,std::string,int>())
>       )

Could get that version to compile, even after adding the (missing ?) policy:
      .def(
          "set"
        , make_function(
              &VirtualNonCopyable::set
            , boost::python::default_call_policies()
            , boost::mpl::vector<void,std::string,int,int>())
      )

Here is the lastest error message...

include\boost\python\detail\invoke.hpp(94) : error C2647: '.*' : cannot
dereference a 'boost::details::compressed_pair_i
mp<T1,T2,Version>::first_type ' on a 'boost::remove_cv<T>::type'
        with
        [
            T1=void (__thiscall VirtualNonCopyable::* )(const std::string
&,int,int),
            T2=boost::python::default_call_policies,
            Version=2
        ]
        and
        [

T=boost::mpl::v_iter<boost::mpl::vector4<void,std::string,int,int>::type,1>:
:type
        ]

Both solutions are of similar complexity to implement in pyste, so it's not
an issue (though, the mpl::vector one avoid a forwarding function, right ?).

> Incidentally, all this applies just as well even after you fix
> Pyste to use new-style polymorphism.

I'll probably look into adding new-style polymorphism sometime in the
future. For now, I'm focusing on fixing all the bugs and getting everything
to work...

Thanks for helping,
Baptiste.




More information about the Cplusplus-sig mailing list