diff --git a/docs/advanced.rst b/docs/advanced.rst index 4353536f..032cf859 100644 --- a/docs/advanced.rst +++ b/docs/advanced.rst @@ -268,8 +268,14 @@ helper class that is defined as follows: The macro :func:`PYBIND11_OVERLOAD_PURE` should be used for pure virtual functions, and :func:`PYBIND11_OVERLOAD` should be used for functions which have -a default implementation. The binding code also needs a few minor adaptations -(highlighted): +a default implementation. + +There are also two alternate macros :func:`PYBIND11_OVERLOAD_PURE_NAME` and +:func:`PYBIND11_OVERLOAD_NAME` which take a string-valued name argument +after the *Name of the function* slot. This is useful when the C++ and Python +versions of the function have different names, e.g. ``operator()`` vs ``__call__``. + +The binding code also needs a few minor adaptations (highlighted): .. code-block:: cpp :emphasize-lines: 4,6,7 diff --git a/example/example12.ref b/example/example12.ref index 2274cddd..a25023fa 100644 --- a/example/example12.ref +++ b/example/example12.ref @@ -1,7 +1,7 @@ Constructing Example12.. Original implementation of Example12::run(state=10, value=20) 30 -Caught expected exception: Tried to call pure virtual function "pure_virtual" +Caught expected exception: Tried to call pure virtual function "Example12::pure_virtual" Constructing Example12.. ExtendedExample12::run(20), calling parent.. Original implementation of Example12::run(state=11, value=21) diff --git a/example/issues.ref b/example/issues.ref index 0bfaca04..4888ea55 100644 --- a/example/issues.ref +++ b/example/issues.ref @@ -1,6 +1,6 @@ const char * c -Failed as expected: Tried to call pure virtual function "dispatch" +Failed as expected: Tried to call pure virtual function "Base::dispatch" Yay.. [Placeholder[1], Placeholder[2], Placeholder[3], Placeholder[4]] [3, 5, 7, 9, 11, 13, 15] diff --git a/include/pybind11/pybind11.h b/include/pybind11/pybind11.h index 02d81e6f..34869eba 100644 --- a/include/pybind11/pybind11.h +++ b/include/pybind11/pybind11.h @@ -1184,19 +1184,25 @@ inline function get_overload(const void *this_ptr, const char *name) { return overload; } -#define PYBIND11_OVERLOAD_INT(ret_type, class_name, name, ...) { \ +#define PYBIND11_OVERLOAD_INT(ret_type, name, ...) { \ pybind11::gil_scoped_acquire gil; \ - pybind11::function overload = pybind11::get_overload(this, #name); \ + pybind11::function overload = pybind11::get_overload(this, name); \ if (overload) \ return overload(__VA_ARGS__).template cast(); } -#define PYBIND11_OVERLOAD(ret_type, class_name, name, ...) \ - PYBIND11_OVERLOAD_INT(ret_type, class_name, name, __VA_ARGS__) \ - return class_name::name(__VA_ARGS__) +#define PYBIND11_OVERLOAD_NAME(ret_type, cname, name, fn, ...) \ + PYBIND11_OVERLOAD_INT(ret_type, name, __VA_ARGS__) \ + return cname::fn(__VA_ARGS__) -#define PYBIND11_OVERLOAD_PURE(ret_type, class_name, name, ...) \ - PYBIND11_OVERLOAD_INT(ret_type, class_name, name, __VA_ARGS__) \ - pybind11::pybind11_fail("Tried to call pure virtual function \"" #name "\""); +#define PYBIND11_OVERLOAD_PURE_NAME(ret_type, cname, name, fn, ...) \ + PYBIND11_OVERLOAD_INT(ret_type, name, __VA_ARGS__) \ + pybind11::pybind11_fail("Tried to call pure virtual function \"" #cname "::" name "\""); + +#define PYBIND11_OVERLOAD(ret_type, cname, fn, ...) \ + PYBIND11_OVERLOAD_NAME(ret_type, cname, #fn, fn, __VA_ARGS__) + +#define PYBIND11_OVERLOAD_PURE(ret_type, cname, fn, ...) \ + PYBIND11_OVERLOAD_PURE_NAME(ret_type, cname, #fn, fn, __VA_ARGS__) NAMESPACE_END(pybind11)