1

Possible Duplicate:
Where and why do I have to put “template” and “typename” on dependent names?

I have following constellation:

template<typename T>
class A{
  template<typename U>
  A<U> f()const;
}

template<typename T, typename U>
A<U> F(const A<T> &I)
{
   return I.f<U>();//this does not work
}

The compiler error on the marked line is: error: expected initializer before ‘>’ token

So how do I write the line correctly?

Community
  • 1
  • 1

2 Answers2

6

That's two-phase lookup for you. Do this:

I.template f<U>();

This is necessary because, when the compiler compiles the function template F(), it does not know what T it might be instantiated with. A could be specialized after the definition of F(), which would only be known the moment F() is actually instantiated. Therefore, when the compiler encounters its definition, I.f<U could also be, say, a comparison between a member f of A<T> with some U.

In order to resolve this ambiguity, you need to tell the compiler that the opening < is actually starting a template instantiation.

sbi
  • 219,715
  • 46
  • 258
  • 445
  • Shame on me I read this in several threads before posting here but did not connect it to my problem. Tanks for the solution and explanation. – Nobody moving away from SE Oct 18 '11 at 16:38
  • Or, in fewer words, you need to *tell* the compiler whether the name "`f`" is a value (say nothing), a typename (say `typename`) or a template (say `template`), since this information is not available at that point. – Kerrek SB Oct 18 '11 at 16:45
4

Try this:

   return I.template f<U>();
Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084