考虑这个例子
template <class T>
struct Foo
{
template <class U> void f (void) {}
void g (void) {}
};
struct Foo2
{
template <class U> void f (void) {}
void g (void) {}
};
template <class T>
struct Bar : public Foo<T>, public Foo2
{
template <class U>
void f (void) {
Foo<T>::f<U> (); // doesn't compile
Foo2::f<U> (); // compiles
}
void g (void) {
Foo<T>::g (); // compiles
Foo2::g (); // compiles
}
};
struct Bar2 : public Foo<char>, public Foo2
{
template <class U>
void f (void) {
Foo<char>::f<U> (); // compiles
Foo2::f<U> (); // compiles
}
void g (void) {
Foo<char>::g (); // compiles
Foo2::g (); // compiles
}
};
int main()
{
Bar<char> b;
b.f<int> ();
b.g ();
Bar2 b2;
b2.f<int> ();
b2.g ();
return 0;
}
在两种继承情况下,模板成员函数f
在子类Bar
和Bar2
中被覆盖。当基类不是模板时,可以从子类中调用重写的方法。当基类是模板但子类不是时,相同。但是,当基类和子类都是模板时,无法从子类调用基类的重写模板成员函数。具体来说,g ++ - 4.8吐出:
In member function ‘void Bar<T>::f()’:
error: expected primary-expression before ‘>’ token
Foo<T>::f<U> (); // doesn't compile
^
error: expected primary-expression before ‘)’ token
Foo<T>::f<U> (); // doesn't compile
^
我的问题是:这是预期的行为吗?
答案 0 :(得分:2)
此处f<U>
是一个从属名称(取决于T
),因此您需要消除它是模板的事实:
Foo<T>::template f<U>();