I've been running into the following problem inside a member function of a templated class:
#include <map>
using std::map;
template <typename A,typename B>
class C {
public:
B f(const A&,const B&) const;
private:
map<A,B> D;
};
template <typename A,typename B>
B C<A,B>::f(const A&a,const B&b) const {
map<A,B>::const_iterator x = D.find(a);
if(x == D.end())
return b;
else
return x->second;
}
When I have g++ compile this I get the following error:
Bug.C: In member function 'B C<A,B>::f(const A&, const B&) const':
Bug.C:12: error:expected ';' before 'x'
Bug.C:13: error: 'x' was not declared in this scope
However, when I make a non-templated version of the class and function, with A and B both being int it compiles without a problem. The error is a little mystifying since I can't imagine why it wants a ';' before the 'x'.
You're missing a typename
:
typename map<A,B>::const_iterator x = D.find(a);
Please read Where and why do I have to put the “template” and “typename” keywords?. The reason you need typename
here is because A
and B
are template parameters which means that the meaning of ::const_iterator
depends on what A
and B
are. While to a human the name const_iterator
makes it obvious that this is an iterator type, to a compiler it doesn't know if this is a type, a data member, etc.
The compiler will do a syntax check on the first pass before templates are instantiated and by adding typename
you letting the compiler know to parse the map<A,B>::const_iterator
as a type.
Also, there is a special rule in C++ (shamefully stolen from the linked question):
A name used in a template declaration or definition and that is dependent on a template-parameter is assumed not to name a type unless the applicable name lookup finds a type name or the name is qualified by the keyword typename.
If you do not add typename
, the compiler has to assume that it is not a type.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With