stl.rst revision 12037
1STL containers 2############## 3 4Automatic conversion 5==================== 6 7When including the additional header file :file:`pybind11/stl.h`, conversions 8between ``std::vector<>``/``std::list<>``/``std::array<>``, 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<>`` 12and ``std::tuple<>`` are already supported out of the box with just the core 13:file:`pybind11/pybind11.h` header. 14 15The major downside of these implicit conversions is that containers must be 16converted (i.e. copied) on every Python->C++ and C++->Python transition, which 17can have implications on the program semantics and performance. Please read the 18next 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_python_types.cpp` contains a complete 27 example that demonstrates how to pass STL data types in more detail. 28 29.. _opaque: 30 31Making opaque types 32=================== 33 34pybind11 heavily relies on a template matching mechanism to convert parameters 35and return values that are constructed from STL data types such as vectors, 36linked lists, hash tables, etc. This even works in a recursive manner, for 37instance to deal with lists of hash maps of pairs of elementary and custom 38types, etc. 39 40However, a fundamental limitation of this approach is that internal conversions 41between Python and C++ types involve a copy operation that prevents 42pass-by-reference semantics. What does this mean? 43 44Suppose we bind the following function 45 46.. code-block:: cpp 47 48 void append_1(std::vector<int> &v) { 49 v.push_back(1); 50 } 51 52and call it from Python, the following happens: 53 54.. code-block:: pycon 55 56 >>> v = [5, 6] 57 >>> append_1(v) 58 >>> print(v) 59 [5, 6] 60 61As you can see, when passing STL data structures by reference, modifications 62are not propagated back the Python side. A similar situation arises when 63exposing STL data structures using the ``def_readwrite`` or ``def_readonly`` 64functions: 65 66.. code-block:: cpp 67 68 /* ... definition ... */ 69 70 class MyClass { 71 std::vector<int> contents; 72 }; 73 74 /* ... binding code ... */ 75 76 py::class_<MyClass>(m, "MyClass") 77 .def(py::init<>()) 78 .def_readwrite("contents", &MyClass::contents); 79 80In this case, properties can be read and written in their entirety. However, an 81``append`` operation involving such a list type has no effect: 82 83.. code-block:: pycon 84 85 >>> m = MyClass() 86 >>> m.contents = [5, 6] 87 >>> print(m.contents) 88 [5, 6] 89 >>> m.contents.append(7) 90 >>> print(m.contents) 91 [5, 6] 92 93Finally, the involved copy operations can be costly when dealing with very 94large lists. To deal with all of the above situations, pybind11 provides a 95macro named ``PYBIND11_MAKE_OPAQUE(T)`` that disables the template-based 96conversion machinery of types, thus rendering them *opaque*. The contents of 97opaque objects are never inspected or extracted, hence they *can* be passed by 98reference. For instance, to turn ``std::vector<int>`` into an opaque type, add 99the declaration 100 101.. code-block:: cpp 102 103 PYBIND11_MAKE_OPAQUE(std::vector<int>); 104 105before any binding code (e.g. invocations to ``class_::def()``, etc.). This 106macro must be specified at the top level (and outside of any namespaces), since 107it instantiates a partial template overload. If your binding code consists of 108multiple compilation units, it must be present in every file preceding any 109usage of ``std::vector<int>``. Opaque types must also have a corresponding 110``class_`` declaration to associate them with a name in Python, and to define a 111set of available operations, e.g.: 112 113.. code-block:: cpp 114 115 py::class_<std::vector<int>>(m, "IntVector") 116 .def(py::init<>()) 117 .def("clear", &std::vector<int>::clear) 118 .def("pop_back", &std::vector<int>::pop_back) 119 .def("__len__", [](const std::vector<int> &v) { return v.size(); }) 120 .def("__iter__", [](std::vector<int> &v) { 121 return py::make_iterator(v.begin(), v.end()); 122 }, py::keep_alive<0, 1>()) /* Keep vector alive while iterator is used */ 123 // .... 124 125The ability to expose STL containers as native Python objects is a fairly 126common request, hence pybind11 also provides an optional header file named 127:file:`pybind11/stl_bind.h` that does exactly this. The mapped containers try 128to match the behavior of their native Python counterparts as much as possible. 129 130The following example showcases usage of :file:`pybind11/stl_bind.h`: 131 132.. code-block:: cpp 133 134 // Don't forget this 135 #include <pybind11/stl_bind.h> 136 137 PYBIND11_MAKE_OPAQUE(std::vector<int>); 138 PYBIND11_MAKE_OPAQUE(std::map<std::string, double>); 139 140 // ... 141 142 // later in binding code: 143 py::bind_vector<std::vector<int>>(m, "VectorInt"); 144 py::bind_map<std::map<std::string, double>>(m, "MapStringDouble"); 145 146Please take a look at the :ref:`macro_notes` before using the 147``PYBIND11_MAKE_OPAQUE`` macro. 148 149.. seealso:: 150 151 The file :file:`tests/test_opaque_types.cpp` contains a complete 152 example that demonstrates how to create and expose opaque types using 153 pybind11 in more detail. 154 155 The file :file:`tests/test_stl_binders.cpp` shows how to use the 156 convenience STL container wrappers. 157