Overloading¶
Introduction¶
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.
Do nothing approach¶
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") ) );
}
“create_with_signature” approach¶
Well, while previous approach is very attractive it does not work in all cases and have a weakness.
Overloaded template function¶
I am sure you already know the following fact, but still I want to remind it:
- GCC-XML doesn’t report about un-instantiated templates
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
.
Do nothing approach weakness¶
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
Overloading using macros¶
Boost.Python provides two macros, which help you to deal with overloaded functions:
BOOST_PYTHON_FUNCTION_OVERLOADS
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS
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.