假设我有以下类层次结构:
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;
}
};
海湾合作委员会吐出以下内容:
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)
现在,如果我将其更改为从已知类型(例如class TestDerived : public virtual TestBase< int >
)实例化的TestBase派生,则此代码段编译得很好,因此问题显然与编译时未知的基类类型有关。但由于我没有在任何地方实例化任何类的对象,我不明白为什么这甚至应该重要。
基本上,如何在不诉诸-fpermissive
的情况下解决错误?
答案 0 :(得分: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;
}
};
答案 1 :(得分:0)
它的美丽不会赢得任何奖项,但这段代码按预期工作,没有编译器抱怨。
virtual int do_bar() {
return ((TestBase<T> *) this)->do_foo() + 1;
}