c++ - 为什么我不能从 C++ 中的派生类实例调用模板化方法?

标签 c++ templates inheritance

请考虑这些类型:

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/

相关文章:

c++ - 重载 operator new/分配超过对象大小

c++ - 构造函数中的通用引用导致失败,无法将可调用仿函数分配给 std::function

c++ - 是否可以仅通过标识符检查成员模板的存在?

c++ - 是否可以在 C++ 中有一个指向模板函数的函数指针?

java - 有没有办法在子类上实现一个方法,我可以从它的子类访问属性?

java - 将子类传递给具有抽象类参数的方法

c++ - 在 C++ 中不重载 operator== 的结构成员相等性

c++ - 为什么右值不能绑定(bind)左值引用?

Sharepoint 中的 Excel 模板 - 如何从模板打开新文件?

c++ - 如何正确实现与基类不同的版本?