Reputation: 1873
I've been searching around for something similar but couldn't find it (or what I found wasn't helpful). I'm trying to be able to have an iterator over a vector of a template class, returning it and using it outside the class, as demonstrated in the code below.
#include <iostream>
#include <vector>
using namespace std;
namespace ns {
template <class T>
class test {
private:
vector<T> container;
public:
typedef vector<T>::iterator iterator;
vector<T>::iterator begin() {
return container.begin();
}
vector<T>::iterator end() {
return container.end();
}
}
};
int main(void) {
test<int> inters;
for (ns::test<int>::iterator i = inters.begin(); i != inters.end(); i++) {
// bla bla bla
}
cout << "end" << endl;
return 0;
}
(you can also check out the code here: http://codepad.org/RuXCYF6T)
I get the following error on line 15:
error: type '__gnu_debug_def::vector<_Tp, std::allocator<_CharT> >' is not derived from type 'ns::test<T>'
compilation terminated due to -Wfatal-errors.
Thanks in advance.
Upvotes: 6
Views: 6785
Reputation: 898
There is lots of discussion about templates and typename and dependent names here. I had a hard time finding that page. Here is the answer I posted there:
Apparently the required syntax is slightly different when the function is not a class member. Note the parentheses around the return type--the compiler complained without them.
template<typename T> (typename std::vector<T>::iterator)
someNonMemberFunction(std::vector<T>& vec, const T& val)
{ return [some std::vector<T>::iterator to an element in vec];
}
Upvotes: 1
Reputation: 168616
I got different errors than you (missing typename
, missing ;
, missing ns::
). Apparently, the different errors messages were from different versions of GCC. You ran this under g++ 4.1.2. I use g++ 4.6.1.
After fixing all of the errors, this works for me:
#include <iostream>
#include <vector>
using namespace std;
namespace ns {
template <class T>
class test {
private:
vector<T> container;
public:
typedef typename vector<T>::iterator iterator; // first change: add typename
typename vector<T>::iterator begin() { // 2nd: add typename
return container.begin();
}
typename vector<T>::iterator end() { // 3rd: add typename
return container.end();
}
}; // 4th: add semi
} // 5th: delete semi
int main(void) {
ns::test<int> inters; // 6th: add ns::
for (ns::test<int>::iterator i = inters.begin(); i != inters.end(); i++) {
// bla bla bla
}
cout << "end\n"; // 7th: avoid endl
return 0;
}
See also: http://codepad.org/gcJBCFOD
Upvotes: 12
Reputation: 31569
You need to use typename
:
typedef typename vector<T>::iterator iterator;
and
typename vector<T>::iterator begin()
typename vector<T>::iterator end()
Edit:
or just use your typedef:
iterator begin()
iterator end()
Upvotes: 4