简体   繁体   English

在模板虚拟类层次结构中调用基类方法

[英]Calling a base class method in a template virtual class hierarchy

Let's say I have the following class hierarchy: 假设我有以下类层次结构:

template< class T >
class TestBase {

public:

    virtual T const & do_foo() = 0;

};

template< class T >
class TestDerived : public virtual TestBase< T > {

public:

    virtual int do_bar() {
        return do_foo() + 1;
    }

};

GCC spits out the following: 海湾合作委员会吐出以下内容:

error: there are no arguments to ‘do_foo’ that depend on a template parameter, so a declaration of ‘do_foo’ must be available [-fpermissive]
note: (if you use ‘-fpermissive’, G++ will accept your code, but allowing the use of an undeclared name is deprecated)

Now, if I change this to derive from a TestBase instantiated from a known type (eg class TestDerived : public virtual TestBase< int > , this snippet compiles just fine so the problem apparently has to do with the base class type being unknown at compile time. But since I haven't instantiated objects of either class anywhere, I don't see why this should even matter. 现在,如果我将其更改为从已知类型实例化的TestBase派生(例如, class TestDerived : public virtual TestBase< int > ,则此代码段编译得很好,因此问题显然与编译时未知的基类类型有关但由于我没有在任何地方实例化任何类的对象,我不明白为什么这甚至应该重要。

Basically, how would I resolve the error without resorting to -fpermissive ? 基本上,如何在不诉诸-fpermissive情况下解决错误?

Non-dependent names (that is, names which do not depend on template arguments), are looked up when parsing the template, not when instantiating it. 在解析模板时,不会在实例化时查找非依赖名称(即,不依赖于模板参数的名称)。 You need to make do_foo a dependent name. 您需要将do_foo作为依赖名称。 There are basically two ways to achieve this: 基本上有两种方法可以实现这一目标:

virtual int do_bar() {
    return this->do_foo() + 1;
}

or 要么

template< class T >
class TestDerived : public virtual TestBase< T > {

public:
    using TestBase<T>::do_foo;

    virtual int do_bar() {
        return do_foo() + 1;
    }

};

It will not win any awards for it's beauty, but this piece of code works as expected, without the compiler complaining. 它的美丽不会赢得任何奖项,但这段代码按预期工作,没有编译器抱怨。

virtual int do_bar() {
    return ((TestBase<T> *) this)->do_foo() + 1;
}

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

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