mis*_*why 3 c++ inheritance templates
请考虑以下类型:
struct X
{
static std::string fullyQualifiedName();
};
struct A
{
template <class T> void foo()
{
return foo(T::fullyQualifiedName());
}
protected:
virtual void foo(const std::string& name) = 0;
};
struct B : public A
{
protected:
void foo(const std::string& name);
};
Run Code Online (Sandbox Code Playgroud)
我有一个指向B实例的指针,我正试图调用这样的模板化版本foo
:
b->foo< X >();
Run Code Online (Sandbox Code Playgroud)
编译器抱怨:'X':非法使用此类型作为表达式.
另一方面,这段代码完全可以:
A* a = b;
a->foo< X >();
Run Code Online (Sandbox Code Playgroud)
因此我的问题.
您面临的问题称为隐藏.基本上,语言中的查找规则将以最派生的类型开始,并以它们的方式返回,直到找到适当的符号.在你的情况下,它会在看到B
它找到的类时停止void B::foo(const std::string& name)
.在那个级别,它将考虑的唯一潜在超载是它所看到的.
为了避免隐藏,您可以带来所有其他重载,您可以添加using
声明:
struct B : A{
using A::foo;
void foo( const std::string & name );
};
Run Code Online (Sandbox Code Playgroud)
不同之处在于查找将处理层次结构,直到找到第一个重载,同样处于B
级别,但由于该using
指令,它还将考虑可用的任何重载A
.
或者,您可以保留符号隐藏并通过限定调用强制调度到完全类(请注意,这具有禁用动态调度的副作用,这在这里不是问题,但可能是如果要使用的重载是虚拟的) :
b->A::foo<X>();
Run Code Online (Sandbox Code Playgroud)