我一直在阅读关于这个主题的不同问题,但是找不到能够解决我正在寻找的问题的问题。这是我的代码模式:
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);
}
执行时我得到:
Template::Foo
Template::Bar
为什么调用bar的运行时调度不起作用?如果我在Derived中重载foo然后它会调用foo的派生版本,为什么它不能为bar进行动态调度?
因为我在现有代码中工作,所以我不想在这里更改类的基本结构。我希望找到一种方法来使呼叫工作,或者理解它为什么不起作用。我在这里阅读其他问题尝试了很多不同的东西,但都无济于事。
答案 0 :(得分:1)
原来这不是模板问题。代码的问题是Derived :: bar方法没有标记为const where,因为TmplClass :: bar方法标记为const。所以,目的是提供一个超越,但实际上Derived :: bar是一个完全不同的方法,具有不同的签名,所以这就是为什么它给出了不期望的行为。从TmplClass :: bar中删除const或将其添加到Derived :: bar后,签名匹配并收到预期的输出:
Template::Foo
Derived::Bar