I'm trying to declare an iterator to a list whose container type is a structure that I have declared inside of a template class. For some reason, I have no problem declaring a reference to this list, but I can not declare an iterator. Here is the code:
#include<vector>
#include<list>
#define DEFAULT_SIZE 8
usingnamespace std;
template <class keyClass,class valClass>
class myHash {
public:
int insert(keyClass& key,valClass& val);
typedefstruct keyVal {
keyClass key;
valClass val;
} keyVal;
private:
int hash_function(keyClass& key);
vector<list<keyVal> > table;
};
template <class keyClass,class valClass> int myHash<keyClass,valClass>::hash_function(keyClass& key) {
int i;
int sum = 0;
unsignedchar* ptr = (unsignedchar*)&key;
for(i=0;i<sizeof(key);i++) {
sum+=ptr[i];
}
return sum;
}
template <class keyClass,class valClass> int myHash<keyClass,valClass>::insert(keyClass& key,valClass& val) {
int bin = hash_function(key) % table.size();
// Check if its there
const list<keyVal>& l = table[bin];
list<keyVal>::iterator iter = l.begin();
// Look for key in list of keyVal
return 0;
}
I get the following compile error:
jon-mac:CODE jonny5cents$ g++ -c test.cpp
test.cpp: In member function ‘int myHash<keyClass, valClass>::insert(keyClass&, valClass&)’:
test.cpp:43: error: expected `;' before ‘iter’
Here's the part that is giving me the issue:
1 2 3 4 5
// Check if its there
const list<keyVal>& l = table[bin];
list<keyVal>::iterator iter = l.begin();
The reference line is fine, but the iterator line gives me a compile error.
Wow, this works. Thanks ... But I don't know why. I've used iterators many times before but I have never had to put class in front of the declaration. For instance, here:
Basically if you're in a template, and a type you're using depends on a templated type, you have to give the typename hint.
For example:
1 2 3 4 5 6 7 8 9 10 11
template <typename T> void foo()
{
vector<T>::iterator i; // bad, vector<T>::iterator might not be a type
// depending on what 'T' is. For example, there might be a specialization
// where iterator is defined as a member var instead of a type.
typename vector<T>::iterator i; // OK
vector<int>::iterator i; // OK, the compiler doesn't need to know what 'T'
// is in order to know what iterator is. Therefore you don't need typename here
}
On another note, you have a const correctness issue:
1 2 3
const list<keyVal>& l = table[bin]; // if 'l' is const
typename list<keyVal>::const_iterator iter = l.begin(); // then you can only get const_iterators