Declare an itearator

Hi,

I have a question.I have to make a class and this class should have a static iterator variable so I can call it as classname::iterator.How can I declare iterators as class members?
Thanks in advance.
Hi !

If I understand what you're asking for, what you want is something like the std::vector<...>::iterator ?

Then, just look at how it is done in the STL for std::vector :
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
  template<typename _Tp, typename _Alloc = allocator<_Tp> >
    class vector : protected _Vector_base<_Tp, _Alloc>
    {
      // Concept requirements.
      __glibcxx_class_requires(_Tp, _SGIAssignableConcept)

      typedef _Vector_base<_Tp, _Alloc>			_Base;
      typedef vector<_Tp, _Alloc>			vector_type;

    public:
      typedef _Tp					 value_type;
      typedef typename _Alloc::pointer                   pointer;
      typedef typename _Alloc::const_pointer             const_pointer;
      typedef typename _Alloc::reference                 reference;
      typedef typename _Alloc::const_reference           const_reference;

// HERE ARE THE ITERATORS:
      typedef __gnu_cxx::__normal_iterator<pointer, vector_type> iterator;
      typedef __gnu_cxx::__normal_iterator<const_pointer, vector_type>
      const_iterator;
      typedef std::reverse_iterator<const_iterator>  const_reverse_iterator;
      typedef std::reverse_iterator<iterator>		 reverse_iterator;
// -----------------------

      typedef size_t					 size_type;
      typedef ptrdiff_t					 difference_type;
      typedef typename _Base::allocator_type		 allocator_type;

and
1
2
      iterator
      begin() { return iterator (this->_M_impl._M_start); }


We can see that you just need to have an iterator class which takes a pointer argument and does what you want with it...

I hope that will help you ;)
I think its a bit complicated this.The class which will have the iterator inside will also have 2 maps(of the same pair of types) and this iterator will traverse them.So, is it enough to write

public static map<string,unsigned>::iterator it;

and with the command

classname::it;

to "call" it??
You can do like that:

1
2
3
4
5
6
7
8
9
10
11
12
class MyClass {

public:
  typedef map<string,unsigned>::iterator iterator;
  iterator begin() {
    return MyMap.begin(); // change this to what you want ;-)
  }

private:
  map<string,unsigned> MyMap;

};


and then you can use

1
2
MyClass instance;
MyClass::iterator it = instance.begin();


Good luck !
Last edited on
Yeap, i think that tis all that I want.And one last thing.Can you tell me what typedef does in the current situation?I mean why do we use typedef here?
Well, the typedef creates a new type inside the class (MyClass::iterator is a type) but using MyClass::iterator is the same as map<string,unsigned>::iterator !

It's often used when MyClass is templated: you can then use the template parameters inside the typedef:

1
2
3
4
5
6
7
8
9
10
11
12
13
14

template<typename tp>
class MyIteratorClass {
  // ...
}

template<typename val>
class MyMainClass {

public:
  typedef val value_type; // value_type is now the same as val (the template parameter)
  typedef MyIteratorClass<value_type> iterator;

}


In that example, MyMainClass<TYPE>::iterator is the same as MyIteratorClass<TYPE> !
Οk.I will try it and I will come back if there are any other questions.
Thanks for now.
Guys, I need a bit more from your help.

I have declared an inner class like this

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
class const_iterator
 {
    public:
    typedef vector<WordScore>::const_iterator iterator;

    iterator legitBegin()
    {
        return legit.begin();

    }

    iterator legitEnd()
    {

        return legit.end();
    }

    iterator spamEnd()
    {

        return spam.end();
    }

    iterator spamBegin()
    {
        return spam.begin();

    }

.
.
.
.//other method declarations
.
}


WordScore is a custom type(created by me) and legit,spam Vectors of WordSize objects.As I am new to this(nested classes) I cant understand what does the folowing errors mean.So I would ask for your precious help here.

error: invalid use of nonstatic data member 'FeatureSelector::legit'

P.S:FeatureSelector is the class that contains the above inner class
I believe you have a declared legit static when it shouldn't have been or you are having a static function access non static data.
No I dont have any static members in my source.If it helps I will post the whole source in an while
Ok, so here is the source code.Every help is precious because the deadline is near, and I cant think something good.
Dont care about the WordScore declaration.Its just a pair of a string and an unsigned....

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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
#ifndef _FEATURESELECTOR_H_
#define _FEATURESELECTOR_H_

#include "wordscore.h"
#include<string>
#include<map>
#include<iostream>
#include<fstream>
#include <vector>
#include <set>
#include<cstring>
#include <exception>
using namespace std;
class FeatureSelector

{
    vector<WordScore> spam;
    vector<WordScore> legit;
    /*Declares two vectors to store the words that appear at least threshold times in the input messages
    and their precisions

    */
    public:
    class const_iter
 {
    public:
    typedef vector<WordScore>::const_iterator iterator;

    iterator const_iter::operator++(int)
    {




    }

    iterator const_iter::iterator legitBegin()
    {
        return legit.begin();

    }

    iterator const_iter::iterator legitEnd()
    {

        return legit.end();
    }

    iterator const_iter::spamEnd()
    {

        return spam.end();
    }

    iterator const_iterat::spamBegin()
    {
        return spam.begin();

    }

     /*prints the data to an output stream regarding if a score option was given*/
      void const_iterator::print(ostream &o,unsigned scores=0)
       {
           if(scores==0)//no score oprion was given from the console
           {
               for(int i=0;i<legit.size();i++)

            {
               cout<<legit[i].getWord<<endl;

            }


            for(int i=0;i<spam.size();i++)
            {
                cout<<spam[i].getScore<<endl;

            }

           }

           else
           {
               for(int i=0;i<spam.size();i++)
               {
                   cout<<spam[i].getWord()<<" ";
                   cout<<spam[i].getScore()<<" ";
                   cout<<findS(spam[i].getWord)<<endl;

               }

           }



       }


        /*
       Given a string from the spam vector returns the associative score from legit vector

       */
       unsigned const_iterator::findS(string s)
       {
           for(int i=0;i<(FeatureSelector::legit).size();i++)
           {
               if(strcmp(legit[i].getWord().c_str(),s.c_str())==0)
               {
                return legit[i].getScore();
               }

           }

           return 0;

       }

 };//class iter



FeatureSelector(string legitFileNames,string spamFileNames,unsigned threshold=10,unsigned scores=0)
{

     map<string,unsigned> legitMap,spamMap,wordsCountLegit,wordsCountSpam;//the first 2 maps will contain info on how may times a word
     //appears totally in legit and spam msgs.The other two contains the number of messages that a word appears.

        try
        {
        ifstream f(legitFileNames.c_str());

        ifstream k(legitFileNames.c_str());



           string input="";
            while(getline(f,input))
            {
                ifstream temp(input.c_str());
                fill_up(legitMap,temp);
                count(&wordsCountLegit,temp);


            }

            //ifstream f(spamFileNames.c_str());

            while(getline(k,input))
            {
                ifstream temp(input.c_str());
                fill_up(spamMap,temp);
                count(&wordsCountSpam,temp);

            }





        map<string, unsigned>::iterator it;
        for(it=legitMap.begin();it!=legitMap.end();it++)
        {
            if((*it).second>=threshold)//if the word appears more than threshlod times calculate the probabilities and store it.
            {
                //calclates the probabilities...legitPrecision(w).
                double x=double(wordsCountLegit[(*it).first]/((wordsCountSpam[(*it).first]+wordsCountLegit[(*it).first])));
                legit.push_back(WordScore((*it).first,x));


            }

        }


            for(it=spamMap.begin();it!=spamMap.end();it++)
            {
             if((*it).second>=threshold)
             {
                 double x=double((wordsCountSpam[(*it).first]/(wordsCountSpam[(*it).first]+wordsCountLegit[(*it).first])));
                 spam.push_back(WordScore((*it).first,x));


             }


            }


            sort(legit.begin(),legit.end());
            sort(spam.begin(),spam.end());

            print(cout,scores);
            print(cout,scores);
        }
      catch(exception &e)
       {
           cout<<"Error occured"<<endl;

       }



    }//end of onstructor



       private:


       /*
       Counts how many times a word from the stream f, appers in the stream(or to the file that the strea points to)
       */
       void count(map<string,unsigned> &m,ifstream f)
       {
           set<string>::iterator it;
           string input="";
           set<string> s;
           while(f>>input)
           {
               s.insert(input);
           }

           for(it=s.begin();it!=s.end();it++)
           {

               m[*it]++;
           }


       }


        /*
        Takes a reference to a map and a reference to an ifstream and fills up the map with stream's data
        */
        void fill_up(map <string,unsigned> &v, ifstream f)
        {
	      string temp;
	      while(f>>temp)
	       {
		    v[temp]++;
           }
       }




};

#endif 
Just because the declaration of const_iter is contained in FeatureSelector does not mean that an instance of const_iter is contained within an instance of FeatureSelector.

That is your compile error.

If you are trying to mimic how STL iterators work, I'm sorry to say that you are not particularly close. I would highly recommend reading stl_vector.h (or the equivalent header) and understanding how iterators were implemented for vectors and use that as a starting point.
Ok, I will try it.Thank you.
Hi !

You need to have two "standard" classes, a "datas" class and an "iterator" class...

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

class Datas;
// now, the compiler knows that Datas is a class so we can use it in the iterator class

class DatasIterator {

public:

    // constructor which takes a reference to the data class
    iterator(Datas& ref) : MyReference(ref) {}

private:

    datas& MyReference;

}

class Datas {

public:

    typedef DatasIterator iterator;

    // if you want the iterator to access private members, I think you could put this:
    // friend class iterator;

    // your functions and everything you want

}
Last edited on
Topic archived. No new replies allowed.