.template (dot-template) construction usage [duplicate]

Possible Duplicate:
Where and why do I have to put the “template” and “typename” keywords?

I've come across a strange segment of code:

#include <iostream>

template <int N>
struct Collection {
  int data[N];

  Collection() {
    for(int i = 0; i < N; ++i) {
      data[i] = 0;
    }
  };

  void SetValue(int v) {
    for(int i = 0; i < N; ++i) {
      data[i] = v;
    }
  };

  template <int I>
  int GetValue(void) const {
    return data[I];
  };
};

template <int N, int I>
void printElement(Collection<N> const & c) {
  std::cout << c.template GetValue<I>() << std::endl; /// doesn't compile without ".template"
}

int main() {
  Collection<10> myc;
  myc.SetValue(5);
  printElement<10, 2>(myc);
  return 0;
}

It is not compiled without .template keyword in printElement function. I've never seen this before and I don't understand what is needed for. Trying to remove it, I got a lot of template-related compilation errors. So my question is when such a construction is used? Is it common?


Solution 1:

GetValue is a dependent name, and so you need to explicitly tell the compiler that what follows c is a function template, not some member data. That is why you need to write template keyword to disambiguate this.

Without template keyword, the following

c.GetValue<I>()  //without template keyword

could be interpreted as:

//GetValue is interpreted as member data, comparing it with I, using < operator
((c.GetValue) < I) > () //attempting to make it a boolean expression

that is, the < is interpreted as less-than operator, and > is interpreted as greater-than operator. The above interpretation is of course incorrect, as it doesn't make sense, and therefore, would result in compilation error.

For more detail explanation, read the accepted answer here:

  • Where and why do I have to put the "template" and "typename" keywords?