请考虑这些类型:
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);
};
我有一个指向 B 实例的指针,我正在尝试调用 foo
的模板化版本,如下所示:
b->foo< X >();
编译器提示:“X”:非法使用此类型作为表达式。
另一方面,这段代码完全没问题:
A* a = b;
a->foo< X >();
因此我的问题。
最佳答案
你面临的问题叫做隐藏。基本上,该语言中的查找规则将从派生程度最高的类型开始,然后一直向上查找,直到找到合适的符号。在您的情况下,它会在查看 B
类时停止,因为它会找到 void B::foo(const std::string& name)
。在该级别,它会考虑的唯一潜在过载是它所看到的。
为了避免隐藏,您可以引入所有其他重载,您可以添加一个 using
声明:
struct B : A{
using A::foo;
void foo( const std::string & name );
};
不同之处在于,查找将在层次结构中向上查找,直到找到第一个重载,这也是在 B
级别,但是由于 using
指令,它将还要考虑 A
中可用的任何重载。
或者,您可以隐藏符号并通过限定调用强制分派(dispatch)到确切的类(请注意,这具有禁用动态分派(dispatch)的副作用,这在这里不是问题,但如果重载使用是虚拟的):
b->A::foo<X>();
关于c++ - 为什么我不能从 C++ 中的派生类实例调用模板化方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6031409/