stl.rst revision 11986:c12e4625ab56
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