Default arguments¶
Introduction¶
There is more than one way to export function with default arguments. Before we proceed, please take a look on the following class:
struct X
{
bool f(int a=12)
{
return true;
}
};
Do nothing approach¶
By default Py++ exposes function with its default arguments.
namespace bp = boost::python;
BOOST_PYTHON_MODULE(pyplusplus){
bp::class_< X >( "X" )
.def(
"f"
, &::X::f
, ( bp::arg("a")=(int)(12) ) );
}
The additional value of the approach is keyword arguments. You will be able to
call function f
like this:
x = X()
x.f( a=13 )
Default values, using macros¶
BOOST_PYTHON_FUNCTION_OVERLOADS
and BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS
macros can help to deal with default values too. You can turn use_overload_macro
to True
:
import module_builder
mb = module_builder.module_builder_t( ... )
x = mb.class_( "X" )
x.member_function( "f" ).use_overload_macro = True
#------------------------^^^^^^^^^^^^^^^^^^^^^^^^^
Registration order problem¶
There is different trades-off between these approaches. In general you should use the first one, until you have “registration order” problem:
struct S1;
struct S2;
struct S1{
void do_smth( S2* s2=0 );
};
struct S2{
void do_smth( S1 s1=S1() );
};
BOOST_PYTHON_MODULE( ... ){
using namespace boost::python;
class_< S2 >( "S2" )
.def( "do_smth", &S2::do_smth, ( arg("s1")=S1() ) );
class_< S1 >( "S1" )
.def( "do_smth", &S1::do_smth, ( arg("s2")=object() ) );
}
The good news is that it is very easy to identify the problem: the module could
not be loaded. The main reason is that expression arg("s1")=S1()
requires
S1
struct to be registered. GCC-XML reports default arguments as strings.
Py++ doesn’t have enough information to generate code with the right class
registration order. In this case you have to instruct Py++ to use macros:
import module_builder
mb = module_builder.module_builder_t( ... )
s2 = mb.class_( "S2" )
s2.member_function( "do_smth" ).use_overload_macro = True
When you switch to macros, than:
- You will not be able to override virtual functions in Python.
- You will not be able to use “named” arguments.
- You will not be able to set the functions documentation.
Special case¶
Class constructors are special case:
struct S1;
struct S2;
struct S1{
S1( S2* s2=0 );
};
struct S2{
S2( S1 s1=S1() );
};
You cannot use same work around and Py++ ( version 0.8.2 ) could not help you. The use case presented here is a little bit esoteric. If you have such use case and you cannot change the source code, consider contacting Py++ developers. I am sure we will be able to help you.