Multiple inheritance support
diff --git a/docs/advanced.rst b/docs/advanced.rst
index 07901e8..d905b30 100644
--- a/docs/advanced.rst
+++ b/docs/advanced.rst
@@ -217,6 +217,8 @@
that demonstrates how to work with callbacks and anonymous functions in
more detail.
+.. _overriding_virtuals:
+
Overriding virtual functions in Python
======================================
@@ -2151,3 +2153,45 @@
};
}
};
+
+Multiple Inheritance
+====================
+
+pybind11 can create bindings for types that derive from multiple base types
+(aka. *multiple inheritance*). To do so, specify all bases in the template
+arguments of the ``class_`` declaration:
+
+.. code-block:: cpp
+
+ py::class_<MyType, BaseType1, BaseType2, BaseType3>(m, "MyType")
+ ...
+
+The base types can be specified in arbitrary order, and they can even be
+interspersed with alias types and holder types (discussed earlier in this
+document)---pybind11 will automatically find out which is which. The only
+requirement is that the first template argument is the type to be declared.
+
+There are two caveats regarding the implementation of this feature:
+
+1. When only one base type is specified for a C++ type that actually has
+ multiple bases, pybind11 will assume that it does not participate in
+ multiple inheritance, which can lead to undefined behavior. In such cases,
+ add the tag ``multiple_inheritance``:
+
+ .. code-block:: cpp
+
+ py::class_<MyType, BaseType2>(m, "MyType", py::multiple_inheritance());
+
+ The tag is redundant and does not need to be specified when multiple base
+ types are listed.
+
+2. As was previously discussed in the section on :ref:`overriding_virtuals`, it
+ is easy to create Python types that derive from C++ classes. It is even
+ possible to make use of multiple inheritance to declare a Python class which
+ has e.g. a C++ and a Python class as bases. However, any attempt to create a
+ type that has *two or more* C++ classes in its hierarchy of base types will
+ fail with a fatal error message: ``TypeError: multiple bases have instance
+ lay-out conflict``. Core Python types that are implemented in C (e.g.
+ ``dict``, ``list``, ``Exception``, etc.) also fall under this combination
+ and cannot be combined with C++ types bound using pybind11 via multiple
+ inheritance.
diff --git a/docs/intro.rst b/docs/intro.rst
index 40dcf35..2559796 100644
--- a/docs/intro.rst
+++ b/docs/intro.rst
@@ -35,12 +35,14 @@
- Instance methods and static methods
- Overloaded functions
- Instance attributes and static attributes
-- Exceptions
+- Arbitrary exception types
- Enumerations
-- Iterators and ranges
- Callbacks
+- Iterators and ranges
- Custom operators
+- Single and multiple inheritance
- STL data structures
+- Iterators and ranges
- Smart pointers with reference counting like ``std::shared_ptr``
- Internal references with correct reference counting
- C++ classes with virtual (and pure virtual) methods can be extended in Python
diff --git a/docs/limitations.rst b/docs/limitations.rst
index c6100d1..a1a4f1a 100644
--- a/docs/limitations.rst
+++ b/docs/limitations.rst
@@ -9,15 +9,12 @@
values. This means that some additional care is needed to avoid bugs that
would be caught by the type checker in a traditional C++ program.
-- Multiple inheritance relationships on the C++ side cannot be mapped to
- Python.
-
- The NumPy interface ``pybind11::array`` greatly simplifies accessing
numerical data from C++ (and vice versa), but it's not a full-blown array
class like ``Eigen::Array`` or ``boost.multi_array``.
-All of these features could be implemented but would lead to a significant
-increase in complexity. I've decided to draw the line here to keep this project
-simple and compact. Users who absolutely require these features are encouraged
-to fork pybind11.
+These features could be implemented but would lead to a significant increase in
+complexity. I've decided to draw the line here to keep this project simple and
+compact. Users who absolutely require these features are encouraged to fork
+pybind11.