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

时间:2015-09-02 15:36:43

标签: c++ templates inheritance

考虑这个例子

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
                       ^

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

1 个答案:

答案 0 :(得分:2)

此处f<U>是一个从属名称(取决于T),因此您需要消除它是模板的事实:

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