github.com/kaydxh/golang@v0.0.131/pkg/gocv/cgo/third_path/pybind11/docs/advanced/cast/stl.rst (about)

     1  STL containers
     2  ##############
     3  
     4  Automatic conversion
     5  ====================
     6  
     7  When including the additional header file :file:`pybind11/stl.h`, conversions
     8  between ``std::vector<>``/``std::deque<>``/``std::list<>``/``std::array<>``/``std::valarray<>``,
     9  ``std::set<>``/``std::unordered_set<>``, and
    10  ``std::map<>``/``std::unordered_map<>`` and the Python ``list``, ``set`` and
    11  ``dict`` data structures are automatically enabled. The types ``std::pair<>``
    12  and ``std::tuple<>`` are already supported out of the box with just the core
    13  :file:`pybind11/pybind11.h` header.
    14  
    15  The major downside of these implicit conversions is that containers must be
    16  converted (i.e. copied) on every Python->C++ and C++->Python transition, which
    17  can have implications on the program semantics and performance. Please read the
    18  next sections for more details and alternative approaches that avoid this.
    19  
    20  .. note::
    21  
    22      Arbitrary nesting of any of these types is possible.
    23  
    24  .. seealso::
    25  
    26      The file :file:`tests/test_stl.cpp` contains a complete
    27      example that demonstrates how to pass STL data types in more detail.
    28  
    29  .. _cpp17_container_casters:
    30  
    31  C++17 library containers
    32  ========================
    33  
    34  The :file:`pybind11/stl.h` header also includes support for ``std::optional<>``
    35  and ``std::variant<>``. These require a C++17 compiler and standard library.
    36  In C++14 mode, ``std::experimental::optional<>`` is supported if available.
    37  
    38  Various versions of these containers also exist for C++11 (e.g. in Boost).
    39  pybind11 provides an easy way to specialize the ``type_caster`` for such
    40  types:
    41  
    42  .. code-block:: cpp
    43  
    44      // `boost::optional` as an example -- can be any `std::optional`-like container
    45      namespace PYBIND11_NAMESPACE { namespace detail {
    46          template <typename T>
    47          struct type_caster<boost::optional<T>> : optional_caster<boost::optional<T>> {};
    48      }}
    49  
    50  The above should be placed in a header file and included in all translation units
    51  where automatic conversion is needed. Similarly, a specialization can be provided
    52  for custom variant types:
    53  
    54  .. code-block:: cpp
    55  
    56      // `boost::variant` as an example -- can be any `std::variant`-like container
    57      namespace PYBIND11_NAMESPACE { namespace detail {
    58          template <typename... Ts>
    59          struct type_caster<boost::variant<Ts...>> : variant_caster<boost::variant<Ts...>> {};
    60  
    61          // Specifies the function used to visit the variant -- `apply_visitor` instead of `visit`
    62          template <>
    63          struct visit_helper<boost::variant> {
    64              template <typename... Args>
    65              static auto call(Args &&...args) -> decltype(boost::apply_visitor(args...)) {
    66                  return boost::apply_visitor(args...);
    67              }
    68          };
    69      }} // namespace PYBIND11_NAMESPACE::detail
    70  
    71  The ``visit_helper`` specialization is not required if your ``name::variant`` provides
    72  a ``name::visit()`` function. For any other function name, the specialization must be
    73  included to tell pybind11 how to visit the variant.
    74  
    75  .. warning::
    76  
    77      When converting a ``variant`` type, pybind11 follows the same rules as when
    78      determining which function overload to call (:ref:`overload_resolution`), and
    79      so the same caveats hold. In particular, the order in which the ``variant``'s
    80      alternatives are listed is important, since pybind11 will try conversions in
    81      this order. This means that, for example, when converting ``variant<int, bool>``,
    82      the ``bool`` variant will never be selected, as any Python ``bool`` is already
    83      an ``int`` and is convertible to a C++ ``int``. Changing the order of alternatives
    84      (and using ``variant<bool, int>``, in this example) provides a solution.
    85  
    86  .. note::
    87  
    88      pybind11 only supports the modern implementation of ``boost::variant``
    89      which makes use of variadic templates. This requires Boost 1.56 or newer.
    90  
    91  .. _opaque:
    92  
    93  Making opaque types
    94  ===================
    95  
    96  pybind11 heavily relies on a template matching mechanism to convert parameters
    97  and return values that are constructed from STL data types such as vectors,
    98  linked lists, hash tables, etc. This even works in a recursive manner, for
    99  instance to deal with lists of hash maps of pairs of elementary and custom
   100  types, etc.
   101  
   102  However, a fundamental limitation of this approach is that internal conversions
   103  between Python and C++ types involve a copy operation that prevents
   104  pass-by-reference semantics. What does this mean?
   105  
   106  Suppose we bind the following function
   107  
   108  .. code-block:: cpp
   109  
   110      void append_1(std::vector<int> &v) {
   111         v.push_back(1);
   112      }
   113  
   114  and call it from Python, the following happens:
   115  
   116  .. code-block:: pycon
   117  
   118     >>> v = [5, 6]
   119     >>> append_1(v)
   120     >>> print(v)
   121     [5, 6]
   122  
   123  As you can see, when passing STL data structures by reference, modifications
   124  are not propagated back the Python side. A similar situation arises when
   125  exposing STL data structures using the ``def_readwrite`` or ``def_readonly``
   126  functions:
   127  
   128  .. code-block:: cpp
   129  
   130      /* ... definition ... */
   131  
   132      class MyClass {
   133          std::vector<int> contents;
   134      };
   135  
   136      /* ... binding code ... */
   137  
   138      py::class_<MyClass>(m, "MyClass")
   139          .def(py::init<>())
   140          .def_readwrite("contents", &MyClass::contents);
   141  
   142  In this case, properties can be read and written in their entirety. However, an
   143  ``append`` operation involving such a list type has no effect:
   144  
   145  .. code-block:: pycon
   146  
   147     >>> m = MyClass()
   148     >>> m.contents = [5, 6]
   149     >>> print(m.contents)
   150     [5, 6]
   151     >>> m.contents.append(7)
   152     >>> print(m.contents)
   153     [5, 6]
   154  
   155  Finally, the involved copy operations can be costly when dealing with very
   156  large lists. To deal with all of the above situations, pybind11 provides a
   157  macro named ``PYBIND11_MAKE_OPAQUE(T)`` that disables the template-based
   158  conversion machinery of types, thus rendering them *opaque*. The contents of
   159  opaque objects are never inspected or extracted, hence they *can* be passed by
   160  reference. For instance, to turn ``std::vector<int>`` into an opaque type, add
   161  the declaration
   162  
   163  .. code-block:: cpp
   164  
   165      PYBIND11_MAKE_OPAQUE(std::vector<int>);
   166  
   167  before any binding code (e.g. invocations to ``class_::def()``, etc.). This
   168  macro must be specified at the top level (and outside of any namespaces), since
   169  it adds a template instantiation of ``type_caster``. If your binding code consists of
   170  multiple compilation units, it must be present in every file (typically via a
   171  common header) preceding any usage of ``std::vector<int>``. Opaque types must
   172  also have a corresponding ``class_`` declaration to associate them with a name
   173  in Python, and to define a set of available operations, e.g.:
   174  
   175  .. code-block:: cpp
   176  
   177      py::class_<std::vector<int>>(m, "IntVector")
   178          .def(py::init<>())
   179          .def("clear", &std::vector<int>::clear)
   180          .def("pop_back", &std::vector<int>::pop_back)
   181          .def("__len__", [](const std::vector<int> &v) { return v.size(); })
   182          .def("__iter__", [](std::vector<int> &v) {
   183             return py::make_iterator(v.begin(), v.end());
   184          }, py::keep_alive<0, 1>()) /* Keep vector alive while iterator is used */
   185          // ....
   186  
   187  .. seealso::
   188  
   189      The file :file:`tests/test_opaque_types.cpp` contains a complete
   190      example that demonstrates how to create and expose opaque types using
   191      pybind11 in more detail.
   192  
   193  .. _stl_bind:
   194  
   195  Binding STL containers
   196  ======================
   197  
   198  The ability to expose STL containers as native Python objects is a fairly
   199  common request, hence pybind11 also provides an optional header file named
   200  :file:`pybind11/stl_bind.h` that does exactly this. The mapped containers try
   201  to match the behavior of their native Python counterparts as much as possible.
   202  
   203  The following example showcases usage of :file:`pybind11/stl_bind.h`:
   204  
   205  .. code-block:: cpp
   206  
   207      // Don't forget this
   208      #include <pybind11/stl_bind.h>
   209  
   210      PYBIND11_MAKE_OPAQUE(std::vector<int>);
   211      PYBIND11_MAKE_OPAQUE(std::map<std::string, double>);
   212  
   213      // ...
   214  
   215      // later in binding code:
   216      py::bind_vector<std::vector<int>>(m, "VectorInt");
   217      py::bind_map<std::map<std::string, double>>(m, "MapStringDouble");
   218  
   219  When binding STL containers pybind11 considers the types of the container's
   220  elements to decide whether the container should be confined to the local module
   221  (via the :ref:`module_local` feature).  If the container element types are
   222  anything other than already-bound custom types bound without
   223  ``py::module_local()`` the container binding will have ``py::module_local()``
   224  applied.  This includes converting types such as numeric types, strings, Eigen
   225  types; and types that have not yet been bound at the time of the stl container
   226  binding.  This module-local binding is designed to avoid potential conflicts
   227  between module bindings (for example, from two separate modules each attempting
   228  to bind ``std::vector<int>`` as a python type).
   229  
   230  It is possible to override this behavior to force a definition to be either
   231  module-local or global.  To do so, you can pass the attributes
   232  ``py::module_local()`` (to make the binding module-local) or
   233  ``py::module_local(false)`` (to make the binding global) into the
   234  ``py::bind_vector`` or ``py::bind_map`` arguments:
   235  
   236  .. code-block:: cpp
   237  
   238      py::bind_vector<std::vector<int>>(m, "VectorInt", py::module_local(false));
   239  
   240  Note, however, that such a global binding would make it impossible to load this
   241  module at the same time as any other pybind module that also attempts to bind
   242  the same container type (``std::vector<int>`` in the above example).
   243  
   244  See :ref:`module_local` for more details on module-local bindings.
   245  
   246  .. seealso::
   247  
   248      The file :file:`tests/test_stl_binders.cpp` shows how to use the
   249      convenience STL container wrappers.