4

假设我有以下类层次结构:

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 吐出以下内容:

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)

现在,如果我将其更改为从从已知类型实例化的 TestBase 派生(例如class TestDerived : public virtual TestBase< int >,此代码段编译得很好,因此问题显然与编译时未知的基类类型有关。但由于我没有实例化对象任何地方的任何一个班级,我都不明白为什么这很重要。

基本上,我将如何在不求助于的情况下解决错误-fpermissive

4

2 回答 2

8

解析模板时会查找非依赖名称(即不依赖于模板参数的名称),而不是在实例化模板时查找。您需要创建do_foo一个从属名称。基本上有两种方法可以实现这一点:

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

或者

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

public:
    using TestBase<T>::do_foo;

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

};
于 2013-01-14T13:14:18.100 回答
0

它不会因为它的美丽而赢得任何奖项,但这段代码按预期工作,编译器没有抱怨。

virtual int do_bar() {
    return ((TestBase<T> *) this)->do_foo() + 1;
}
于 2013-01-14T13:17:58.483 回答