6

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.

takecare
  • 1,684
  • 3
  • 21
  • 32
  • 1
    Shouldn't it be `ns::test inters;`? And don't use `using namespace std;` if you can help it. – Kerrek SB Oct 18 '11 at 16:23
  • 1
    And, where is the ';' after your class declaration? Is this the **actual** code that gives you that error, or is it something *just like* the code that gave the error? Please copy-paste (don't retype) an actual, minimal, complete program that demonstrates the error. – Robᵩ Oct 18 '11 at 16:27
  • I restract my implicit accusation. This is the actual code (as evidenced by the codepad link). The codepad only shows the first error. @user would have found the other errors in due time. – Robᵩ Oct 18 '11 at 16:42
  • possible duplicate of [Where and why do I have to put "template" and "typename" on dependent names?](http://stackoverflow.com/questions/610245/where-and-why-do-i-have-to-put-template-and-typename-on-dependent-names) – sbi Oct 18 '11 at 16:51

3 Answers3

12

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

Robᵩ
  • 163,533
  • 20
  • 239
  • 308
  • Also, if you have the typedef you can use it in your `begin` and `end` member functions – pmr Oct 18 '11 at 16:39
  • thanks. I searched some more, and after a few minutes I stumbled in the "typedef typename" solution (that is, it was lacking the typename since vector wasn't instantiated - right?). sorry for the other errors (like missing ';') but I did type this example quickly just to illustrate the problem, since the "original" code was kind of extensive to paste. – takecare Oct 18 '11 at 16:41
4

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()
Daniel
  • 30,896
  • 18
  • 85
  • 139
1

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];
}
Community
  • 1
  • 1
riderBill
  • 818
  • 9
  • 16