Blame external/pybind11/docs/advanced/cast/functional.rst

Packit 534379
Functional
Packit 534379
##########
Packit 534379
Packit 534379
The following features must be enabled by including :file:`pybind11/functional.h`.
Packit 534379
Packit 534379
Packit 534379
Callbacks and passing anonymous functions
Packit 534379
=========================================
Packit 534379
Packit 534379
The C++11 standard brought lambda functions and the generic polymorphic
Packit 534379
function wrapper ``std::function<>`` to the C++ programming language, which
Packit 534379
enable powerful new ways of working with functions. Lambda functions come in
Packit 534379
two flavors: stateless lambda function resemble classic function pointers that
Packit 534379
link to an anonymous piece of code, while stateful lambda functions
Packit 534379
additionally depend on captured variables that are stored in an anonymous
Packit 534379
*lambda closure object*.
Packit 534379
Packit 534379
Here is a simple example of a C++ function that takes an arbitrary function
Packit 534379
(stateful or stateless) with signature ``int -> int`` as an argument and runs
Packit 534379
it with the value 10.
Packit 534379
Packit 534379
.. code-block:: cpp
Packit 534379
Packit 534379
    int func_arg(const std::function<int(int)> &f) {
Packit 534379
        return f(10);
Packit 534379
    }
Packit 534379
Packit 534379
The example below is more involved: it takes a function of signature ``int -> int``
Packit 534379
and returns another function of the same kind. The return value is a stateful
Packit 534379
lambda function, which stores the value ``f`` in the capture object and adds 1 to
Packit 534379
its return value upon execution.
Packit 534379
Packit 534379
.. code-block:: cpp
Packit 534379
Packit 534379
    std::function<int(int)> func_ret(const std::function<int(int)> &f) {
Packit 534379
        return [f](int i) {
Packit 534379
            return f(i) + 1;
Packit 534379
        };
Packit 534379
    }
Packit 534379
Packit 534379
This example demonstrates using python named parameters in C++ callbacks which
Packit 534379
requires using ``py::cpp_function`` as a wrapper. Usage is similar to defining
Packit 534379
methods of classes:
Packit 534379
Packit 534379
.. code-block:: cpp
Packit 534379
Packit 534379
    py::cpp_function func_cpp() {
Packit 534379
        return py::cpp_function([](int i) { return i+1; },
Packit 534379
           py::arg("number"));
Packit 534379
    }
Packit 534379
Packit 534379
After including the extra header file :file:`pybind11/functional.h`, it is almost
Packit 534379
trivial to generate binding code for all of these functions.
Packit 534379
Packit 534379
.. code-block:: cpp
Packit 534379
Packit 534379
    #include <pybind11/functional.h>
Packit 534379
Packit 534379
    PYBIND11_MODULE(example, m) {
Packit 534379
        m.def("func_arg", &func_arg);
Packit 534379
        m.def("func_ret", &func_ret);
Packit 534379
        m.def("func_cpp", &func_cpp);
Packit 534379
    }
Packit 534379
Packit 534379
The following interactive session shows how to call them from Python.
Packit 534379
Packit 534379
.. code-block:: pycon
Packit 534379
Packit 534379
    $ python
Packit 534379
    >>> import example
Packit 534379
    >>> def square(i):
Packit 534379
    ...     return i * i
Packit 534379
    ...
Packit 534379
    >>> example.func_arg(square)
Packit 534379
    100L
Packit 534379
    >>> square_plus_1 = example.func_ret(square)
Packit 534379
    >>> square_plus_1(4)
Packit 534379
    17L
Packit 534379
    >>> plus_1 = func_cpp()
Packit 534379
    >>> plus_1(number=43)
Packit 534379
    44L
Packit 534379
Packit 534379
.. warning::
Packit 534379
Packit 534379
    Keep in mind that passing a function from C++ to Python (or vice versa)
Packit 534379
    will instantiate a piece of wrapper code that translates function
Packit 534379
    invocations between the two languages. Naturally, this translation
Packit 534379
    increases the computational cost of each function call somewhat. A
Packit 534379
    problematic situation can arise when a function is copied back and forth
Packit 534379
    between Python and C++ many times in a row, in which case the underlying
Packit 534379
    wrappers will accumulate correspondingly. The resulting long sequence of
Packit 534379
    C++ -> Python -> C++ -> ... roundtrips can significantly decrease
Packit 534379
    performance.
Packit 534379
Packit 534379
    There is one exception: pybind11 detects case where a stateless function
Packit 534379
    (i.e. a function pointer or a lambda function without captured variables)
Packit 534379
    is passed as an argument to another C++ function exposed in Python. In this
Packit 534379
    case, there is no overhead. Pybind11 will extract the underlying C++
Packit 534379
    function pointer from the wrapped function to sidestep a potential C++ ->
Packit 534379
    Python -> C++ roundtrip. This is demonstrated in :file:`tests/test_callbacks.cpp`.
Packit 534379
Packit 534379
.. note::
Packit 534379
Packit 534379
    This functionality is very useful when generating bindings for callbacks in
Packit 534379
    C++ libraries (e.g. GUI libraries, asynchronous networking libraries, etc.).
Packit 534379
Packit 534379
    The file :file:`tests/test_callbacks.cpp` contains a complete example
Packit 534379
    that demonstrates how to work with callbacks and anonymous functions in
Packit 534379
    more detail.