Possible Duplicate:
Where and why do I have to put the “template” and “typename” keywords?
I’ve (had to 🙂 ) became a C++ developer a few weeks ago (I had some experiences before but not too much, I was more in Java), trying to learn everything which counts and to develop as efficient as I can. So excuse if my question is totally dumb. I have a problem with a simple example template class:
template<typename T>
class SameCounter {
private:
map<T,int> counted;
public:
SameCounter(list<T> setup) {
for(list<T>::iterator it = setup.begin(); it != setup.end(); it++) {
counted[*it]++;
}
}
map<T,int>::const_iterator& begin() { // line 25
return counted.begin();
}
map<T,int>::const_iterator& end() {
return counted.end();
}
};
...
// using the class
Reader rdr;
rdr.Read();
SameCounter<char> sc(rdr.GetData());
I get some error when I’m compiling it:
Error 3 error C4430: missing type specifier - int assumed. Note: C++ does not support default-int d:\learn_cpp\examples\gyakorlas_1.cpp 25
Error 2 error C2143: syntax error : missing ';' before '&' d:\learn_cpp\examples\gyakorlas_vizsga\gyakorlas_1.cpp 25
(both of them twice)
I don’t have a clue for it, something is wrong maybe with the templating I assume, because if I create the SameCounter as a normal class it is totally ok. Thank you for the help.
This should help you:
C++ templates are tricky. T is a template parameter, and
map<T, int>::const_iteratorcould possibly mean different things (type names, but also – say – static members…) depending on what T you pass.That’s why in templates sometimes you need to make your intention clear and indicate that you actually mean “
const_iteratoris a type and I want a reference to it”. The keyword ‘typename’ allows for that.See: http://pages.cs.wisc.edu/~driscoll/typename.html
To make your code simpler and
avoidreduce the need fortypename, you could start with:and then just go with
Unfortunately this
typenamestill needs to be here, you’d need furthertypedef typenamefor each dependent type to remove it from further declarations (see @rhalbersma‘s answer).Following @rhalbersma‘s comment, let me also emphasise that you should return these iterators by-value. Returning references to temporaries causes undefined behaviour because the object gets out of scope and you end up with a “dangling reference”.
So make it: