-1

I'm trying to implement virtual-less callbacks. I would expect the following code to compile, since Foo is base of Bar and it includes an implementation of DoAct(X*). However, the compiler errors out if Bar doesn't include all the methods of Foo.

Shouldn't the compiler be able to pick Foo::DoAct(X*) without fuzz?

Windows 10; MSVC 16.11.2; 64bits

error C2664: 'void Bar::DoAct(Y *)': cannot convert argument 1 from 'X *' to 'Y *'
struct X {};
struct Y {};

template<typename T>
struct Foo  {
    void DoAct(X* x) {}
    void DoAct(Y* y) {}

    void Act(X* x) {
        static_cast<T*>(this)->DoAct(x);
    }
};

struct Bar : Foo<Bar> {
    //void DoAct(X*) {}   /// XXX: Works if present, fails if commented.
    void DoAct(Y*) {}
};


TEST_CASE("Test") {
    Bar b;
    X x;

    b.Act(&x);
}

Dess
  • 2,064
  • 19
  • 35
  • This has nothing to do with virtual functions, you are running into the "hiding rule": https://isocpp.org/wiki/faq/strange-inheritance#hiding-rule – UnholySheep Sep 06 '21 at 22:08
  • `using Foo::DoAct;` will make the `Foo` version visible. Another solution is to explicitly name the scope when calling the function from the outside: `b.Foo::DoAct(&x);` – Stack Danny Sep 06 '21 at 22:27

1 Answers1

0

Try adding using Foo::DoAct in Bar. That should bring the inherited DoAct into the scope, in addition to its own DoAct.

numzero
  • 2,009
  • 6
  • 6