Back to home page

EIC code displayed by LXR

 
 

    


Warning, /jana2/src/python/externals/pybind11-2.10.3/docs/advanced/cast/functional.rst is written in an unsupported language. File is not indexed.

0001 Functional
0002 ##########
0003 
0004 The following features must be enabled by including :file:`pybind11/functional.h`.
0005 
0006 
0007 Callbacks and passing anonymous functions
0008 =========================================
0009 
0010 The C++11 standard brought lambda functions and the generic polymorphic
0011 function wrapper ``std::function<>`` to the C++ programming language, which
0012 enable powerful new ways of working with functions. Lambda functions come in
0013 two flavors: stateless lambda function resemble classic function pointers that
0014 link to an anonymous piece of code, while stateful lambda functions
0015 additionally depend on captured variables that are stored in an anonymous
0016 *lambda closure object*.
0017 
0018 Here is a simple example of a C++ function that takes an arbitrary function
0019 (stateful or stateless) with signature ``int -> int`` as an argument and runs
0020 it with the value 10.
0021 
0022 .. code-block:: cpp
0023 
0024     int func_arg(const std::function<int(int)> &f) {
0025         return f(10);
0026     }
0027 
0028 The example below is more involved: it takes a function of signature ``int -> int``
0029 and returns another function of the same kind. The return value is a stateful
0030 lambda function, which stores the value ``f`` in the capture object and adds 1 to
0031 its return value upon execution.
0032 
0033 .. code-block:: cpp
0034 
0035     std::function<int(int)> func_ret(const std::function<int(int)> &f) {
0036         return [f](int i) {
0037             return f(i) + 1;
0038         };
0039     }
0040 
0041 This example demonstrates using python named parameters in C++ callbacks which
0042 requires using ``py::cpp_function`` as a wrapper. Usage is similar to defining
0043 methods of classes:
0044 
0045 .. code-block:: cpp
0046 
0047     py::cpp_function func_cpp() {
0048         return py::cpp_function([](int i) { return i+1; },
0049            py::arg("number"));
0050     }
0051 
0052 After including the extra header file :file:`pybind11/functional.h`, it is almost
0053 trivial to generate binding code for all of these functions.
0054 
0055 .. code-block:: cpp
0056 
0057     #include <pybind11/functional.h>
0058 
0059     PYBIND11_MODULE(example, m) {
0060         m.def("func_arg", &func_arg);
0061         m.def("func_ret", &func_ret);
0062         m.def("func_cpp", &func_cpp);
0063     }
0064 
0065 The following interactive session shows how to call them from Python.
0066 
0067 .. code-block:: pycon
0068 
0069     $ python
0070     >>> import example
0071     >>> def square(i):
0072     ...     return i * i
0073     ...
0074     >>> example.func_arg(square)
0075     100L
0076     >>> square_plus_1 = example.func_ret(square)
0077     >>> square_plus_1(4)
0078     17L
0079     >>> plus_1 = func_cpp()
0080     >>> plus_1(number=43)
0081     44L
0082 
0083 .. warning::
0084 
0085     Keep in mind that passing a function from C++ to Python (or vice versa)
0086     will instantiate a piece of wrapper code that translates function
0087     invocations between the two languages. Naturally, this translation
0088     increases the computational cost of each function call somewhat. A
0089     problematic situation can arise when a function is copied back and forth
0090     between Python and C++ many times in a row, in which case the underlying
0091     wrappers will accumulate correspondingly. The resulting long sequence of
0092     C++ -> Python -> C++ -> ... roundtrips can significantly decrease
0093     performance.
0094 
0095     There is one exception: pybind11 detects case where a stateless function
0096     (i.e. a function pointer or a lambda function without captured variables)
0097     is passed as an argument to another C++ function exposed in Python. In this
0098     case, there is no overhead. Pybind11 will extract the underlying C++
0099     function pointer from the wrapped function to sidestep a potential C++ ->
0100     Python -> C++ roundtrip. This is demonstrated in :file:`tests/test_callbacks.cpp`.
0101 
0102 .. note::
0103 
0104     This functionality is very useful when generating bindings for callbacks in
0105     C++ libraries (e.g. GUI libraries, asynchronous networking libraries, etc.).
0106 
0107     The file :file:`tests/test_callbacks.cpp` contains a complete example
0108     that demonstrates how to work with callbacks and anonymous functions in
0109     more detail.