Virtual Method calling another virtual method in a templatized class

82 views Asked by At

I've been reading different questions on this topic, but haven't been able to find one that quite answers what I'm looking for. Here's the pattern of code that I have:

class Base {
public:
    virtual void foo(int) const {...}
}

template <class T>
class TmplClass : public Base {
public:
    virtual void foo(int i) const { foo(T(i)); }
    virtual void foo(T& param) const {
        printf("Template::Foo\n");
        bar(param);
    }
    virtual void bar(T&) const {
        printf("Template::Bar\n");
    }
}

class Derived : public TmplClass<SomeConcreteType> {
public:
    void bar(SomeConcreteType&) {
        printf("Derived::Bar\n");
    }
}

int main() {
    Derived d;
    Base* b = &d;
    b->foo(1);
}

On execution I get:

Template::Foo
Template::Bar

Why doesn't the run-time dispatch on the call to bar work? If I overload foo in Derived then it does call the derived version of foo, why can't it do the dynamic dispatch for bar?

Because I'm working in existing code, I would prefer not to change the basic structure of the classes here. I'm hoping to just find a way to make the call work, or understand why it doesn't. I've tried lots of different things based on reading other questions here, but all to no avail.

1

There are 1 answers

0
Daniel Skarbek On BEST ANSWER

Turns out this wasn't a template issue. The problem with the code is that the Derived::bar method is not marked as const where-as the TmplClass::bar method is marked const. So, the intention was to provide an over-ride, but actually Derived::bar is a totally different method with a different signature, so that's why it was giving un-expected behavior. Once the const is removed from TmplClass::bar or added to the Derived::bar then the signatures match and the expected output is received:

Template::Foo
Derived::Bar