pybind11
pybind11 copied to clipboard
[BUG]: expose lifted private/protected methods from non-exposed base class cause compile errors on MSVC
Required prerequisites
- [X] Make sure you've read the documentation. Your issue may be addressed there.
- [X] Search the issue tracker and Discussions to verify that this hasn't already been reported. +1 or comment there if it has.
- [X] Consider asking first in the Gitter chat room or in a Discussion.
What version (or hash if on master) of pybind11 are you using?
2.10.3
Problem description
In the MSVC17.5.5 version (Windows10 19045.2965), when compiling with C++20, the derived class cannot export the method that is privately inherited in multiple inheritance but promoted to public, resulting in a compilation error.
The error message is as follows: error C2247: 'Mixined' is not accessible because 'Derived' inherits from 'Mixined' using 'private'.
But I don't want to expose any information of the Mixin class in Python, I just want to export the method
Using a lambda method wrapper for every method that is promoted to public can solve this problem, but in my project, which uses this kind of private inheritance a lot to add functionality, creating a lambda for each one seems a bit too annoying.
#1124 seems to be the same problem, but so far only lambda seems to be the solution?
Can anyone give me some help? I would be grateful!
Reproducible example code
#include <iostream>
#include <pybind11/pybind11.h>
struct Base {
void base_fun() {
std::cout << "base function.\n";
}
};
struct Mixined {
void mixin_fun() {
std::cout << "mixined function.\n";
}
};
struct Derived : public Base, private Mixined /*just add functions*/{
using Mixined::mixin_fun; // lifted to public
};
namespace py = pybind11;
PYBIND11_MODULE(test_module, m) {
py::class_<Base>(m, "Base")
.def(::py::init<>())
.def("base_fun", &Base::base_fun);
py::class_<Derived, Base>(m, "Derived")
.def(::py::init<>())
.def("mixin_fun", &Derived::mixin_fun); // get compiler errors for can not cast to mixined class
// .def("mixin_fun",[](Derived& d) {d.mixin_fun();});// use lambda is ok, but i have too many mixined methods
}
Is this a regression? Put the last known working version here if it is.
Not a regression
#include <iostream>
#include <pybind11/pybind11.h>
struct Base {
void base_fun() {
std::cout << "base function.\n";
}
};
struct Mixined {
void mixin_fun() {
std::cout << "mixined function.\n";
}
};
struct Derived : public Base, private Mixined {
using Mixined::mixin_fun; // lifted to public
// Explicitly expose the mixin_fun method to Python
void exposed_mixin_fun() {
mixin_fun(); // Call the mixin_fun method from Mixined
}
};
namespace py = pybind11;
PYBIND11_MODULE(test_module, m) {
py::class_<Base>(m, "Base")
.def(py::init<>())
.def("base_fun", &Base::base_fun);
py::class_<Derived, Base>(m, "Derived")
.def(py::init<>())
.def("exposed_mixin_fun", &Derived::exposed_mixin_fun); // Bind the exposed method
}