Add informative compilation failure for method_adaptor failures #1127
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
When using
method_adaptor
(usually implicitly via acl.def("f", &D::f)
) a compilation failure results iff
is actually a method of an inaccessible base class made public viausing
, such as:pybind deduces
&D::f
as aB
member function pointer. Since the base class is inaccessible, the cast inmethod_adaptor
from a base class member function pointer to derived class member function pointer isn't valid, and a cast failure results.This was sort of a regression in 2.2, which introduced
method_adaptor
to do the expected thing when the base class is accessible. It wasn't actually something that worked in 2.1, though: you wouldn't get a compile-time failure, but the method was not callable (because theD *
couldn't be cast to aB *
because of the access restriction). As a result, you'd simply get a run-time failure if you ever tried to call the function (this is what #855 fixed). Thus the change in 2.2 essentially promoted a run-time failure to a compile-time failure, so isn't really a regression.This commit simply adds a
static_assert
with an accessible-base-class check so that, rather than just a cryptic cast failure, you get something more informative (along with a suggestion for a workaround).The workaround is to use a lambda, e.g.:
This is a bit of a nuissance (especially if there are a bunch of arguments to forward), but I don't really see another solution.
Fixes #1124