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.