Things get a little bit complex, when you have to export overloaded functions. In general the solution is to explicitly say to compiler what function you want to export, by specifying its type. Before we proceed, please take a look on the following class:
struct X
{
bool f(int a)
{
return true;
}
bool f(int a, double b)
{
return true;
}
bool f(int a, double b, char c)
{
return true;
}
};
This class has been taken from Boost.Python tutorials.
There are few approaches, which you can use in order to export the functions.
I am sure you will like “do nothing” approach. Py++ recognize that you want to export an overloaded function and will generate the right code:
namespace bp = boost::python;
BOOST_PYTHON_MODULE(pyplusplus){
bp::class_< X >( "X" )
.def(
"f"
, (bool ( ::X::* )( int ) )( &::X::f )
, ( bp::arg("a") ) )
.def(
"f"
, (bool ( ::X::* )( int,double ) )( &::X::f )
, ( bp::arg("a"), bp::arg("b") ) )
.def(
"f"
, (bool ( ::X::* )( int,double,char ) )( &::X::f )
, ( bp::arg("a"), bp::arg("b"), bp::arg("c") ) );
}
Well, while previous approach is very attractive it does not work in all cases and have a weakness.
I am sure you already know the following fact, but still I want to remind it:
It is very important to understand it. Lets take a look on the following source code:
struct Y{
void do_smth( int );
template< class T>
void do_smth( T t );
};
If you didn’t instantiate( use ) do_smth member function, than GCC-XML will not report it. As a result, Py++ will not be aware of the fact that do_smth is an overloaded function. To make the long story short, the generated code will not compile. You have to instruct Py++ to generate code, which contains function type:
from pyplusplus import module_builder
mb = module_builder.module_builder_t( ... )
y = mb.class_( 'Y' )
y.member_function( 'do_smth' ).create_with_signature = True
#------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Every Py++ class, which describes C++ function\operator has create_with_signature property. You have to set it to True. Default value of the property is computed. If the exported function is overloaded, then its value is True otherwise it will be False.
Code modification - the weakness of the “do nothing” approach. We live in the dynamic world. You can create bindings for a project, but a month letter, the project developers will add a new function to the exported class. Lets assume that the new function will introduce overloading. If create_with_signature has False as a value, than the previously generated code will not compile and you will have to run code generator one more time.
Consider to explicitly set create_with_signature to True. It will save your and your users time in future.
mb = module_builder_t( ... )
mb.calldefs().create_with_signature = True
Boost.Python provides two macros, which help you to deal with overloaded functions:
Boost.Python tutorials contain an explanation about this macros.
You can instruct Py++ to generate code, which will use the macros:
import module_builder
mb = module_builder.module_builder_t( ... )
x = mb.class_( "X" )
x.member_functions( "f" ).use_overload_macro = True
#-------------------------^^^^^^^^^^^^^^^^^^^^^^^^^
Member and free functions declaration classes have use_overload_macro property. The default value of the property is False.
You don’t really have to use the macros, unless you have “registration order” problem. The problem and work around described in default arguments document.