Ahh, C++ templates...
The code I see,
makes sense to me,
but GCC...
it disagrees.
The following code compiles and runs as expected, but if you uncomment that #define
, you get the error, which I don't understand. The symbol iterator
still has only one thing it can refer to: the typedef in the superclass. So I guess I have two questions: 1. What do the errors mean? 2. What is the best way to fix them.
#include <map>
#include <string>
#include <cstdio>
using namespace std;
// #define WITH_TEMPLATE 1
#ifdef WITH_TEMPLATE
template <class C>
struct MyClass : public map<string, C>
#else
struct MyClass : public map<string, int>
#endif
{
bool haskey(const string &s)
{
iterator it = find(s);
return (it != end());
}
};
int main()
{
#ifdef WITH_TEMPLATE
MyClass<int> m;
#else
MyClass m;
#endif
m["test"] = 10;
printf("%d %d\n", m.haskey("test"), m.haskey("no"));
}
Errors from GCC:
temp.cc: In member function ‘bool MyClass::haskey(const std::string&)’:
temp.cc:18: error: missing template arguments before ‘it’
temp.cc:18: error: expected `;' before ‘it’
temp.cc:19: error: ‘it’ was not declared in this scope
temp.cc:19: error: there are no arguments to ‘end’ that depend on a template parameter, so a declaration of ‘end’ must be available
temp.cc:19: error: (if you use ‘-fpermissive’, G++ will accept your code, but allowing the use of an undeclared name is deprecated)
You need to change your MyClass::haskey method too.
bool haskey(const string &s)
{
typename MyClass<C>::iterator it = this->find(s);
return (it != this->end());
}
Explanation of such a behavior is in section "Name lookup, templates, and accessing members of base classes" on http://physics.ucsd.edu/students/courses/winter2008/physics141/manuals/rhel-gcc-en-4/c---misunderstandings.html (link from another answer's comment, just in case).
Whole fixed example code: http://ideone.com/G7Rty
iterator it = find(s);
return (it != end());
This line should be as,
#ifdef WITH_TEMPLATE
typename map<string, C>::iterator it = this->find(s);
return (it != this->end());
#else
map<string, int>::iterator it = find(s);
return (it != end());
#endif
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