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() //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?