【发布时间】:2021-09-06 22:01:48
【问题描述】:
我正在尝试实现无虚拟回调。我希望以下代码能够编译,因为 Foo 是 Bar 的基础,并且它包含 DoAct(X*) 的实现。但是,如果Bar 没有包含 Foo 的所有方法,编译器就会出错。
编译器不应该能够在没有模糊的情况下选择Foo::DoAct(X*)吗?
Windows 10; MSVC 16.11.2; 64位
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);
}
【问题讨论】:
-
这与虚函数无关,你遇到了“隐藏规则”:isocpp.org/wiki/faq/strange-inheritance#hiding-rule
-
using Foo<Bar>::DoAct;将使Foo版本可见。另一种解决方案是在从外部调用函数时显式命名作用域:b.Foo<Bar>::DoAct(&x);
标签: c++