2

Why is the following code invalid?

template <typename S, typename T>
struct B{
    void f(T t, S s) {t.f<S>(s); }
};

gcc 4.3.4 complains that it "expected primary-expression before '>' token", i.e. that "S" wasn't a valid primary-expression.

pythonic metaphor
  • 10,296
  • 18
  • 68
  • 110

2 Answers2

12

You need to specify that f is a template:

void f(T t, S s) {
    t.template f<S>(s);
}

C++ doesn’t know this (at this point) since f’s type depends on the type of the template parameter T. Furthermore, the following syntax would be ambiguous: does < mean the start of a template list or a less-than operator? To help C++ figure that out you need to specify that f is a template, otherwise C++ cannot parse the following part because the parse itself depends on the type of T.

Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
  • VS can parse it though (lazy parsing?), it's just a C++ standard restriction – coyotte508 Sep 21 '11 at 14:10
  • @coyotte508 VS uses a two-pass parser to handle this. This is of course possible, but quite inefficient. The restriction of a single pass in the standard makes a lot of sense, especially considering that computers weren’t always as fast as today, and C++ compilers are *still* very slow. – Konrad Rudolph Sep 21 '11 at 15:36
  • That's great to know. It's not the only instance in which GCC behaves this way (something with it requiring to use using BaseClass::function if BaseClass is a template parameter), so personnally I don't mind trading some compilation time for this, but I understand now why the restriction. – coyotte508 Sep 21 '11 at 15:52
1

You also can rely on type inference to infer the template type instead of explicitly stating it. Then you would have "t.f(s);", which is actually a slightly more generic way to state it: you probably don't care that f is a templated function, you just want it to have some definition for f that accepts an S.

Chris Pitman
  • 12,990
  • 3
  • 41
  • 56
  • I think type inference would have failed in the actual code, because of polymorphism. f looked like template void f(S&), and I wanted to instantiate f(Child&), which isn't clear from the example code. – pythonic metaphor Jun 11 '10 at 20:39