pybind11/include/pybind11
Jason Rhinelander 2097826346 Fix template trampoline overload lookup failure
Problem
=======

The template trampoline pattern documented in PR #322 has a problem with
virtual method overloads in intermediate classes in the inheritance
chain between the trampoline class and the base class.

For example, consider the following inheritance structure, where `B` is
the actual class, `PyB<B>` is the trampoline class, and `PyA<B>` is an
intermediate class adding A's methods into the trampoline:

    PyB<B> -> PyA<B> -> B -> A

Suppose PyA<B> has a method `some_method()` with a PYBIND11_OVERLOAD in
it to overload the virtual `A::some_method()`.  If a Python class `C` is
defined that inherits from the pybind11-registered `B` and tries to
provide an overriding `some_method()`, the PYBIND11_OVERLOADs declared
in PyA<B> fails to find this overloaded method, and thus never invoke it
(or, if pure virtual and not overridden in PyB<B>, raises an exception).

This happens because the base (internal) `PYBIND11_OVERLOAD_INT` macro
simply calls `get_overload(this, name)`; `get_overload()` then uses the
inferred type of `this` to do a type lookup in `registered_types_cpp`.
This is where it fails: `this` will be a `PyA<B> *`, but `PyA<B>` is
neither the base type (`B`) nor the trampoline type (`PyB<B>`).  As a
result, the overload fails and we get a failed overload lookup.

The fix
=======

The fix is relatively simple: we can cast `this` passed to
`get_overload()` to a `const B *`, which lets get_overload look up the
correct class.  Since trampoline classes should be derived from `B`
classes anyway, this cast should be perfectly safe.

This does require adding the class name as an argument to the
PYBIND11_OVERLOAD_INT macro, but leaves the public macro signatures
unchanged.
2016-08-29 19:41:44 -04:00
..
attr.h avoid C++ -> Python -> C++ overheads when passing around function objects 2016-07-10 10:44:44 +02:00
cast.h Added pybind11::make_key_iterator for map iteration 2016-08-11 21:22:05 -04:00
common.h minor fixes to PR #368 2016-08-28 02:03:15 +02:00
complex.h nicer type_caster::load() calling conventions 2016-05-15 20:23:27 +02:00
descr.h Use fully qualified name in PYBIND11_DESCR macro 2016-08-13 12:43:16 +01:00
eigen.h Simplify code in eigen.h using new array ctors 2016-08-15 18:41:54 +01:00
eval.h Python 2.7 fixes for eval() 2016-07-08 15:14:48 +02:00
functional.h type_caster<std::function>: allow None values in both directions 2016-08-18 11:18:12 +02:00
numpy.h minor: renamed argument in array constructor 2016-08-28 01:55:07 +02:00
operators.h minor Intel compiler fix 2016-08-26 16:52:45 +02:00
pybind11.h Fix template trampoline overload lookup failure 2016-08-29 19:41:44 -04:00
pytypes.h Add handle::repr() method 2016-08-14 13:43:31 +01:00
stl_bind.h Add support for iterators with differing end type 2016-08-24 23:29:04 +01:00
stl.h Adopt PEP 484 type hints for C++ types exported to Python 2016-08-04 23:47:07 +02:00
typeid.h minor cleanups in common.h; updated author info and copyright year 2016-04-18 10:53:38 +02:00