从模板子类调用模板基类的重写模板成员函数

Calling overridden template member function of template base class from template subclass

本文关键字:重写 成员 函数 调用 子类 基类      更新时间:2023-10-16

考虑以下示例

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在子类BarBar2中被覆盖。当基类不是模板时,可以从子类调用被重写的方法。当基类是模板而子类不是模板时,相同。但是,当基类和子类都是模板时,基类的重写模板成员函数不能从子类中调用。具体来说,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
                       ^

我的问题是:这是预期行为吗?

这里f<U>是一个依赖名称(它取决于T),所以您需要消除它是一个模板的事实:

Foo<T>::template f<U>();