[C++-sig] Bug when exporting function overloaded on base and derived classes

Roman Yakovenko roman.yakovenko at gmail.com
Sat Feb 10 19:54:15 CET 2007


On 2/9/07, Edson Tadeu <e.tadeu at gmail.com> wrote:
> Hi,
>  I've found a bug where Boost.Python calls the wrong function overload. Here
> is a small unit test:
>
> =====
> The C++ module "_test.cpp":
> =====
>
> #include <boost/python.hpp>
> #include <string>
>
> class Base { };
>
> class Derived : public Base { };
>
> std::string f(Base& b) {
>     return "Base";
> }
>
> std::string f(Derived& d) {
>     return "Derived";
> }
>
>  BOOST_PYTHON_MODULE( _test )
> {
>     using namespace boost::python;
>
>     class_<Base>("Base");
>     class_<Derived, bases<Base> >("Derived");
>
>     def("f", static_cast<std::string (*)(Derived&)>(&f));
>     def("f", static_cast<std::string (*)(Base&)>(&f));
> }
>
>
> =====
> The small test in python:
> =====
>
> >>> from _test import *
> >>> f(Base())
> 'Base'
> >>> f(Derived())
> 'Base'
>
>
> =====
>
> Interestingly enough, if the function overloads are exported in the inverse
> order, it actually works, i.e., if using this code:
>
> =====
>  BOOST_PYTHON_MODULE( _test )
>  {
>      using namespace boost::python;
>
>      class_<Base>("Base");
>      class_<Derived, bases<Base> >("Derived");
>
>      def("f", static_cast<std::string (*)(Base&)>(&f));
>      def("f", static_cast<std::string (*)(Derived&)>(&f));
> }
> =====
>
> I do not know very well how does the boost.python registry works, but it
> seems that it is selecting the first match instead of testing all matches
> and selecting the "best one".

There are cases where it is impossible to select the best match:
void do_smth( char )
void do_smth( const char* )

Any way this pitfall explained here:
http://language-binding.net/pyplusplus/documentation/functions/registration_order.html#registration-order-pitfalls
-- 
Roman Yakovenko
C++ Python language binding
http://www.language-binding.net/



More information about the Cplusplus-sig mailing list