0

Consider this example

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;
}

In both inheritance cases, the template member function f is overridden in the subclasses Bar and Bar2. When the base class is not a template, the overridden method can be called just fine from the subclass. When the base class is a template but the subclass is not, the same. But, when both the base class and subclass are templates, the overridden template member function of the base class cannot be called from the subclass. Specifically, g++-4.8 spits out:

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
                       ^

My question is: is this expected behavior?

user2601195
  • 161
  • 2
  • 9

1 Answers1

2

Here f<U> is a dependent name (it depends on T), so you need to disambiguate the fact that it is a template :

Foo<T>::template f<U>();
Quentin
  • 62,093
  • 7
  • 131
  • 191