C++ Using a class template argument as a template argument for another type
I'm having this problem while writing my own HashTable. It all works, but when I try to templatize the thing, it gave me errors. I recreated the problem as follows:
THIS CODE WORKS:
typedef double Item;
class A
{
public:
A()
{
v.push_back(pair<string, Item>("hey", 5.0));
}
void iterate()
{
for(Iterator iter = v.begin(); iter != v.end(); ++iter)
cout << iter->first << ", " << iter->second << endl;
}
private:
vector<pair<string, double> > v;
typedef vector< pair<string, double> >::iterator Iterator;
};
THIS CODE DOES NOT:
template<typename ValueType>
class B
{
public:
B(){}
void iterate()
{
for(Iterator iter = v.begin(); iter != v.end(); ++iter)
cout << iter->first << ", " << iter->second << endl;
}
private:
vector<pair<string, ValueType> > v;
typedef vector< pair<string, ValueType> >::iterator Iterator;
};
the error messages: g++ -O0 -g3 -Wall -c -fmessage-length=0 -omain.o ..\main.cpp
..\main.cpp:50: error: type std::vector<std::pair<std::string, ValueType>, std::allocator<std::pair<std::string, ValueType> > >' is not derived from type
B'
..\main.cpp:50: error: ISO C++ forbids declaration of `iterator' with no type
..\main.cpp:50: error: expected `;' before "Iterator"
..\main.cpp: In member function `void B::iterate()':开发者_如何学JAVA
..\main.cpp:44: error: `Iterator' was not declared in this scope
..\main.cpp:44: error: expected `;' before "iter"
..\main.cpp:44: error: `iter' was not declared in this scope
Does anybody know why this is happening? Thanks!
This is called "dependent names" in C++. In your second code snippet, you say:
typedef vector< pair<string, ValueType> >::iterator Iterator;
whereas you should say:
typedef typename vector< pair<string, ValueType> >::iterator Iterator;
Whenever you see an error saying "is not derived...", typename is to the rescue. In general, the idea is that the compiler doesn't know if iterator is a type or a variable, because it doesn't know what
vector< pair <string, ValueType> >
is, as it depends on ValueType.
(Afraid I'm not using the right terms here, but the idea is correct)
thanks it works and all makes sense now!
And i don't want to use a typedef, I can also use typename like this:
for( typename list<pair<string, ValueType> >::const_iterator itr = v.begin(); itr != v.end() ; ++itr){
{
//code
}
精彩评论