I have base classes with virtual methods fun. I need to redefine all fun methods in a derived class. I know of SO: C++ virtual override functions with same name, but it does not work for me.
Function processDerived accepts v1::Derived *. If I pass v2::Derived * there it does not work as expected.
class Base1 {
public:
    virtual ~Base1() {}
    virtual void funB1_1() {}
    virtual void funB1_2() {}
    virtual void fun() { std::cout << "Base1::fun()" << std::endl; }
};
class Base2 {
public:
    virtual ~Base2() {}
    virtual void fun() { std::cout << "Base2::fun()" << std::endl; }
    virtual void funB2() {}
};
namespace v1 {
    class Derived : public Base1, public Base2 {
        int x_;
    public:
        Derived() : x_(10) {}
        virtual ~Derived() {}
        virtual void funD1(int i) { std::cout << "Derived::funD1(" << i << ")" << std::endl; }
    };
}
namespace v2 {
    class Base1Proxy : public Base1 {
    public:
        virtual ~Base1Proxy() {}
        virtual void fun() override { fun_Base1(); }
    protected:
        virtual void fun_Base1() = 0;
    };
    class Base2Proxy : public Base2 {
    public:
        virtual ~Base2Proxy() {}
        virtual void fun() override { fun_Base2(); }
    protected:
        virtual void fun_Base2() = 0;
    };
    class Derived : public Base1Proxy, public Base2Proxy {
        int x_;
    public:
        Derived() : x_(10) {}
        virtual ~Derived() {}
        virtual void funD1(int i) { std::cout << "Derived::funD1(" << i << ")" << std::endl; }
    protected:
        virtual void fun_Base1() override { std::cout << "Derived::Base1::fun(), x = " << x_ << std::endl; }
        virtual void fun_Base2() override { std::cout << "Derived::Base2::fun(), x = " << x_ << std::endl; }
    };
}
void processDerived(v1::Derived * d, int i) {
    d->funD1(i);
}
int main() {
    v1::Derived d;
    Base1 * b1 = &d;
    Base2 * b2 = &d;
    b1->fun();
    b2->fun();
    processDerived(&d, 100);
    v2::Derived d2;
    b1 = &d2;
    b2 = &d2;
    b1->fun();
    b2->fun();
    processDerived(reinterpret_cast<v1::Derived *>(&d2), 200);
}
Output:
Base1::fun()
Base2::fun()
Derived::funD1(100)
Derived::Base1::fun(), x = 10
Derived::Base2::fun(), x = 10
Derived::Base1::fun(), x = 10  // expected Derived::funD1(200)
VTABLES (generated by MSVC):
;   COMDAT ??_7Derived@v2@@6BBase2Proxy@1@@
CONST   SEGMENT
??_7Derived@v2@@6BBase2Proxy@1@@ DQ FLAT:??_R4Derived@v2@@6BBase2Proxy@1@@ ; v2::Derived::`vftable'
    DQ  FLAT:??_EDerived@v2@@W7EAAPEAXI@Z
    DQ  FLAT:?fun@Base2Proxy@v2@@UEAAXXZ
    DQ  FLAT:?funB2@Base2@@UEAAXXZ
    DQ  FLAT:?fun_Base2@Derived@v2@@MEAAXXZ
CONST   ENDS
;   COMDAT ??_7Derived@v2@@6BBase1Proxy@1@@
CONST   SEGMENT
??_7Derived@v2@@6BBase1Proxy@1@@ DQ FLAT:??_R4Derived@v2@@6BBase1Proxy@1@@ ; v2::Derived::`vftable'
    DQ  FLAT:??_EDerived@v2@@UEAAPEAXI@Z
    DQ  FLAT:?funB1_1@Base1@@UEAAXXZ
    DQ  FLAT:?funB1_2@Base1@@UEAAXXZ
    DQ  FLAT:?fun@Base1Proxy@v2@@UEAAXXZ
    DQ  FLAT:?fun_Base1@Derived@v2@@MEAAXXZ
    DQ  FLAT:?funD1@Derived@v2@@UEAAXH@Z
CONST   ENDS
;   COMDAT ??_7Base2Proxy@v2@@6B@
CONST   SEGMENT
??_7Base2Proxy@v2@@6B@ DQ FLAT:??_R4Base2Proxy@v2@@6B@  ; v2::Base2Proxy::`vftable'
    DQ  FLAT:??_EBase2Proxy@v2@@UEAAPEAXI@Z
    DQ  FLAT:?fun@Base2Proxy@v2@@UEAAXXZ
    DQ  FLAT:?funB2@Base2@@UEAAXXZ
    DQ  FLAT:_purecall
CONST   ENDS
;   COMDAT ??_7Base1Proxy@v2@@6B@
CONST   SEGMENT
??_7Base1Proxy@v2@@6B@ DQ FLAT:??_R4Base1Proxy@v2@@6B@  ; v2::Base1Proxy::`vftable'
    DQ  FLAT:??_EBase1Proxy@v2@@UEAAPEAXI@Z
    DQ  FLAT:?funB1_1@Base1@@UEAAXXZ
    DQ  FLAT:?funB1_2@Base1@@UEAAXXZ
    DQ  FLAT:?fun@Base1Proxy@v2@@UEAAXXZ
    DQ  FLAT:_purecall
CONST   ENDS
;   COMDAT ??_7Derived@v1@@6BBase2@@@
CONST   SEGMENT
??_7Derived@v1@@6BBase2@@@ DQ FLAT:??_R4Derived@v1@@6BBase2@@@ ; v1::Derived::`vftable'
    DQ  FLAT:??_EDerived@v1@@W7EAAPEAXI@Z
    DQ  FLAT:?fun@Base2@@UEAAXXZ
    DQ  FLAT:?funB2@Base2@@UEAAXXZ
CONST   ENDS
;   COMDAT ??_7Derived@v1@@6BBase1@@@
CONST   SEGMENT
??_7Derived@v1@@6BBase1@@@ DQ FLAT:??_R4Derived@v1@@6BBase1@@@ ; v1::Derived::`vftable'
    DQ  FLAT:??_EDerived@v1@@UEAAPEAXI@Z
    DQ  FLAT:?funB1_1@Base1@@UEAAXXZ
    DQ  FLAT:?funB1_2@Base1@@UEAAXXZ
    DQ  FLAT:?fun@Base1@@UEAAXXZ
    DQ  FLAT:?funD1@Derived@v1@@UEAAXH@Z
CONST   ENDS
;   COMDAT ??_7Base2@@6B@
CONST   SEGMENT
??_7Base2@@6B@ DQ FLAT:??_R4Base2@@6B@          ; Base2::`vftable'
    DQ  FLAT:??_EBase2@@UEAAPEAXI@Z
    DQ  FLAT:?fun@Base2@@UEAAXXZ
    DQ  FLAT:?funB2@Base2@@UEAAXXZ
CONST   ENDS
;   COMDAT ??_7Base1@@6B@
CONST   SEGMENT
??_7Base1@@6B@ DQ FLAT:??_R4Base1@@6B@          ; Base1::`vftable'
    DQ  FLAT:??_EBase1@@UEAAPEAXI@Z
    DQ  FLAT:?funB1_1@Base1@@UEAAXXZ
    DQ  FLAT:?funB1_2@Base1@@UEAAXXZ
    DQ  FLAT:?fun@Base1@@UEAAXXZ
CONST   ENDS
As you can see method (1) is called instead of (2)
; old Derived::`vftable'
DQ  FLAT:??_EDerived@v1@@UEAAPEAXI@Z
DQ  FLAT:?funB1_1@Base1@@UEAAXXZ
DQ  FLAT:?funB1_2@Base1@@UEAAXXZ
DQ  FLAT:?fun@Base1@@UEAAXXZ
DQ  FLAT:?funD1@Derived@v1@@UEAAXH@Z
; new Derived::`vftable'
DQ  FLAT:??_EDerived@v2@@UEAAPEAXI@Z
DQ  FLAT:?funB1_1@Base1@@UEAAXXZ
DQ  FLAT:?funB1_2@Base1@@UEAAXXZ
DQ  FLAT:?fun@Base1Proxy@v2@@UEAAXXZ
DQ  FLAT:?fun_Base1@Derived@v2@@MEAAXXZ   ; <== (1)
DQ  FLAT:?funD1@Derived@v2@@UEAAXH@Z      ; <== (2)
Is there a solution for my case?
P.S. I know of MSVC-specific solution but I need it to work for GCC, Clang, Apple-Clang.
 
    