The source code and dockerfile for the GSW2024 AI Lab.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.

109 lines
3.8 KiB

2 months ago
  1. Functional
  2. ##########
  3. The following features must be enabled by including :file:`pybind11/functional.h`.
  4. Callbacks and passing anonymous functions
  5. =========================================
  6. The C++11 standard brought lambda functions and the generic polymorphic
  7. function wrapper ``std::function<>`` to the C++ programming language, which
  8. enable powerful new ways of working with functions. Lambda functions come in
  9. two flavors: stateless lambda function resemble classic function pointers that
  10. link to an anonymous piece of code, while stateful lambda functions
  11. additionally depend on captured variables that are stored in an anonymous
  12. *lambda closure object*.
  13. Here is a simple example of a C++ function that takes an arbitrary function
  14. (stateful or stateless) with signature ``int -> int`` as an argument and runs
  15. it with the value 10.
  16. .. code-block:: cpp
  17. int func_arg(const std::function<int(int)> &f) {
  18. return f(10);
  19. }
  20. The example below is more involved: it takes a function of signature ``int -> int``
  21. and returns another function of the same kind. The return value is a stateful
  22. lambda function, which stores the value ``f`` in the capture object and adds 1 to
  23. its return value upon execution.
  24. .. code-block:: cpp
  25. std::function<int(int)> func_ret(const std::function<int(int)> &f) {
  26. return [f](int i) {
  27. return f(i) + 1;
  28. };
  29. }
  30. This example demonstrates using python named parameters in C++ callbacks which
  31. requires using ``py::cpp_function`` as a wrapper. Usage is similar to defining
  32. methods of classes:
  33. .. code-block:: cpp
  34. py::cpp_function func_cpp() {
  35. return py::cpp_function([](int i) { return i+1; },
  36. py::arg("number"));
  37. }
  38. After including the extra header file :file:`pybind11/functional.h`, it is almost
  39. trivial to generate binding code for all of these functions.
  40. .. code-block:: cpp
  41. #include <pybind11/functional.h>
  42. PYBIND11_MODULE(example, m) {
  43. m.def("func_arg", &func_arg);
  44. m.def("func_ret", &func_ret);
  45. m.def("func_cpp", &func_cpp);
  46. }
  47. The following interactive session shows how to call them from Python.
  48. .. code-block:: pycon
  49. $ python
  50. >>> import example
  51. >>> def square(i):
  52. ... return i * i
  53. ...
  54. >>> example.func_arg(square)
  55. 100L
  56. >>> square_plus_1 = example.func_ret(square)
  57. >>> square_plus_1(4)
  58. 17L
  59. >>> plus_1 = func_cpp()
  60. >>> plus_1(number=43)
  61. 44L
  62. .. warning::
  63. Keep in mind that passing a function from C++ to Python (or vice versa)
  64. will instantiate a piece of wrapper code that translates function
  65. invocations between the two languages. Naturally, this translation
  66. increases the computational cost of each function call somewhat. A
  67. problematic situation can arise when a function is copied back and forth
  68. between Python and C++ many times in a row, in which case the underlying
  69. wrappers will accumulate correspondingly. The resulting long sequence of
  70. C++ -> Python -> C++ -> ... roundtrips can significantly decrease
  71. performance.
  72. There is one exception: pybind11 detects case where a stateless function
  73. (i.e. a function pointer or a lambda function without captured variables)
  74. is passed as an argument to another C++ function exposed in Python. In this
  75. case, there is no overhead. Pybind11 will extract the underlying C++
  76. function pointer from the wrapped function to sidestep a potential C++ ->
  77. Python -> C++ roundtrip. This is demonstrated in :file:`tests/test_callbacks.cpp`.
  78. .. note::
  79. This functionality is very useful when generating bindings for callbacks in
  80. C++ libraries (e.g. GUI libraries, asynchronous networking libraries, etc.).
  81. The file :file:`tests/test_callbacks.cpp` contains a complete example
  82. that demonstrates how to work with callbacks and anonymous functions in
  83. more detail.