2015-09-02 60 views
0

模板基类的重写的模板构件函数考虑这个例子调用从模板子类

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 
        ^

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

回答

2

这里f<U>是一个从属名称(这取决于T),所以你需要消除歧义的事实,这是一个模板:

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