| Default Arguments

Boost.Python wraps (member) function pointers. Unfortunately, C++ function pointers carry no default argument info. Take a function `f` with default arguments:

`

        int f(int, double = 3.14, char const* = "hello");

`

But the type of a pointer to the function `f` has no information about its default arguments:

`

        int(*g)(int,double,char const*) = f;    // defaults lost!

`

When we pass this function pointer to the `def` function, there is no way to retrieve the default arguments:

`

        def("f", f);                            // defaults lost!

`

Because of this, when wrapping C++ code in earlier versions of Boost.Python, we had to resort to writing thin wrappers:

`

        // write "thin wrappers"
        int f1(int x) { f(x); }
        int f2(int x, double y) { f(x,y); }

        /*...*/

            // in module init
            def("f", f);  // all arguments
            def("f", f2); // two arguments
            def("f", f1); // one argument

`

When you want to wrap functions (or member functions) that either:

- have default arguments, or
- are overloaded with a common sequence of initial arguments

Boost.Python now has a way to make it easier.

For instance, given a function:

`

        int foo(int a, char b = 1, unsigned c = 2, double d = 3);

`

The macro invocation:

`

        BOOST_PYTHON_FUNCTION_OVERLOADS(foo_overloads, foo, 1, 4)

`

Will automatically create the thin wrappers for us. This macro will create a class `foo_overloads` that can be passed on to `def(...)`. The third and fourth macro argument are the minimum arguments and maximum arguments, respectively. In our `foo` function the minimum number of arguments is 1 and the maximum number of arguments is 4. The `def(...)` function will automatically add all the foo variants for us:

`

        .def("foo", foo, foo_overloads());

`

A similar facility is provided for class constructors, again, with default arguments or a sequence of overloads. Remember init<...>? For example, given a class X with a constructor:

`

        struct X
        {
            X(int a, char b = 'D', std::string c = "constructor", double d = 0.0);
            /*...*/
        }

`

You can easily add this constructor to Boost.Python in one shot:

`

        .def(init<int, optional<char, std::string, double> >())

`

Notice the use of `init<...>` and `optional<...>` to signify the default (optional arguments).

Copyright © 2002 David Abrahams
Copyright © 2002 Joel de Guzman
Permission to copy, use, modify, sell and distribute this document is granted provided this copyright notice appears in all copies. This document is provided "as is" without express or implied warranty, and with no claim as to its suitability for any purpose.