pybind / pybind/pybind11

[BUG]: expose lifted private/protected methods from non-exposed base class cause compile errors on MSVC

Open
#4,675 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

triage
Dominant language
C++
Stars
18k
Forks
2.3k
Avg merge
5d 17h
Merged PRs (30d)
10

Description

Required prerequisites
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

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the PYBIND11_MODULE example with MSVC 17.5.5 and C++20, focusing on py::class_<Derived, Base>::def("mixin_fun", &Derived::mixin_fun). Inspect how this binding entry handles a method lifted from the privately inherited Mixined class. Done means the promoted method compiles and binds without requiring a per-method lambda wrapper.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp, python
Domain
developer-experience, tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.