Implementation problems with template classes and iterators?

Hi, I am coding a little tree-container-class.
It is using list and vector to store the nodes and the data in.
Now, there is a template class nodeInfo<class T,class nodeType> which stores the node id, parent id, the node-describing data (type: nodeType) and the values (in a vector<T>).
Class tree is declared as template <class T, class nodeType> class tree.
So far, no problems.
But now I'm having a little conflict with iterators on the list. The list is implemented as list<nodeInfo<T, nodeType> > (what is still okay).
Iterators on that list should accordingly be declared as list<nodeInfo<T, nodeType> >::iterator. But somehow the compiler seems to misunderstand this type, seeing an invalid type list<nodeInfo<T,nodeType> and >::iterator what both does not make sense.
When I try to use: list<nodeInfo<T,nodeType> >::iterator iter = nodes.begin()+nodeId;
The error I get is "expected ; before iter".
list<nodeInfo<T,nodeType>>::iterator iter = nodes.begin()+nodeId; also does not work (because >> should be > > (is mixed up with operator>>)).
So, list<nodeInfo<T,nodeType> >::iterator is a type I can not declare. But I can still USE it (for example for a function call like: "(nodes.begin()+nodeId)->vals.push_back(value);").
This simply does not seem to make sense, does it?
Is there another way to get rid of this problem than using the value directly without storing, returning or modifying an iterator?
Last edited on
Well, it is hard to figure out what is wrong just from your (crowded) description. This is what I wrote and it works fine.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <iostream>
#include <vector>
#include <list>
#include <string>

using namespace std;

template <class T, class nodeType>
class nodeInfo
  {
  public:
    unsigned   id;
    unsigned   parent_id;
    nodeType   data;
    vector <T> values;
  };

template <class T, class nodeType>
class tree: public list< nodeInfo <T, nodeType> >
  {
  public:
    typedef nodeInfo <T, nodeType> node_t;
  };

int main()
  {
  tree <int, int> t;

  tree <int, int>::node_t n;
    n.id = 12;
    n.parent_id = 0;
    n.data = 99;
    n.values.push_back( 1 );
    n.values.push_back( 2 );

  t.push_back( n );

  for (tree <int, int>::iterator i = t.begin(); i != t.end(); i++)
    {
    cout << i->id << endl;
    for (vector<int>::iterator j = i->values.begin();
         j != i->values.end();
         j++)
      cout << "  " << *j << endl;
    }

  return 0;
  }


You should be handling things similarly. Hope this helps.
You are somehow bypassing the problem by inheriting list. Good idea, thanks ;).
For this case, it is a good solution but what about the problem in general?
Why does:
class1<class2<type1,type2> >::iterator
refuse to work?
Last edited on
I still don't know what
class1< class2< type1, type2 > >::iterator
means. Without specific types I can't offer more specific help than that for this particular example, class1 must inherit from a standard container.

[edit] Oh, I think I get it. You want a member field of type std::list...
The type must match.
If your class1 does not inherit from a container type, you can't say class1::iterator.

Note line 41 of my example. I can't say anything about the node or tree types, because the type of the iterator has nothing to do with it.

[edit 2]
Of course, I can make a type:
1
2
3
4
5
6
class nodeInfo
  {
  ...

  typedef vector <T>::iterator iterator;
  };

then use it below:
 
  for (tree <int, int>::node_t::iterator = i->values.begin()...


Hope this helps.
Last edited on
Sure, but I think you do not understand...^^
class1 is a container-class (list in my case)...
The type I meant is existing and can be USED, but not directly declared...
Just try to compile this, and you will see what I mean:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
template <class I, class J> class T
{
      int a;
      //values in here
};
template <class I, class J> class A
{
      list<T<I,J> > listvals;
      void f1()
      {
             T<I,J> t;
             listvals.push_back(t);
             list<T<I,J> >::iterator iter = listvals.begin();
             iter->a = 15;
             //do something
      }
};



But:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
template <class I, class J> class T
{
      int a;
      //values in here
};

template <class I, class J> class A
{
      list<T<I,J> > listvals;
      void f1()
      {
             T<I,J> t;
             listvals.push_back(t);
             listvals.begin()->a = 15;
             //do something
      }
};


works...
typedef seems to be a good solution, it is simply a misunderstanding of the line
list<T<I,J> >::iterator iter = listvals.begin();
Last edited on
Ah, that's a better explanation. I get it now.

The problem is that for line 13 you are using a type as an lvalue. You must explicitly indicate that it is a type with:
typename list<T<I,J> >::iterator iter = ...

Welcome to your sanity. :-D

[edit] BTW, thanks for your patience...
Last edited on
It is okay ;). Thanks to you for your fast explanation...^^ Just forgot about typename.
Topic archived. No new replies allowed.