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