繁体   English   中英

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

[英]Why can't I call a templated method from a derived class instance in C++?

请考虑以下类型:

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可用的任何重载。

或者,您可以保留符号隐藏并通过限定调用强制调度到完全类(请注意,这具有禁用动态调度的副作用,这在这里不是问题,但可能是如果要使用的重载是虚拟的) :

b->A::foo<X>();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM