Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > user-defined iterator

Reply
Thread Tools

user-defined iterator

 
 
vasili
Guest
Posts: n/a
 
      06-15-2007
hello All,

I have a simple issue.
I defined a custom container, that encloses a std::list, which in turn
holds objects that are a simple abstraction of a six position array.

Now, i would like to serialize the whole newly-defined container, in
order to copy the contents to another array. So i thought to define an
iterator which represented a "pointer" to the container's data. But,
when i feed these iterators to std::copy the compiler complains about
a lot of types which are defined when a std::iterator is instanced.

the code:

//i leave all unnecessary stuff out just to be clear
#include <list>

using namespace std;

class SixBytes{
public: //i don't trash the example with any accessor methods
char m_data[6];
};

class MyCont{
list<SixBytes> m_list;
public:
class Iterator{
const MyCont& m_cont;
int m_index;
public:
Iterator(const MyCont& cnt, int index=0):m_cont(cnt),
m_index(index){}
Iterator operator++(int){//postfix? just placed this
and the following methods to be "complete" //
w.r.t. the requirements of the std::copy algorithm and to this example
Iterator ret(*this);
m_index++;
return ret;
}
Iterator& operator++(){//prefix?
m_index++;
return *this;
}
char operator*(){
//...return the byte that corresponds to the
position m_
index
}
};

inline Iterator begin() const{ return Iterator(*this); }//the
start of the serialization
inline const Iterator end() const { return Iterator(*this,
m_list.size()*6); }//it's end
MyCont(){ m_list.push_back(SixBytes());
m_list.push_back(SixBytes());}
};

int main(){
char data[13];
data[0] = 2;
MyCont m;
std::copy(m.begin(), m.end(), data+1);
}//example ends here

giving this to the compiler i get this:

/usr/lib/gcc/i586-mandrake-linux-gnu/3.4.1/../../../../include/c++/
3.4.1/bits/stl_iterator_base_types.h: In instantiation of
`std::iterator_traits<MyCont::Iterator>':
/usr/lib/gcc/i586-mandrake-linux-gnu/3.4.1/../../../../include/c++/
3.4.1/bits/stl_algobase.h:305: instantiated from `_OutputIterator
std::__copy_ni2(_InputIterator, _InputIterator, _OutputIterator,
__false_type) [with _InputIterator = MyCont::Iterator, _OutputIterator
= char*]'
/usr/lib/gcc/i586-mandrake-linux-gnu/3.4.1/../../../../include/c++/
3.4.1/bits/stl_algobase.h:327: instantiated from `_OutputIterator
std::__copy_ni1(_InputIterator, _InputIterator, _OutputIterator,
__false_type) [with _InputIterator = MyCont::Iterator, _OutputIterator
= char*]'
/usr/lib/gcc/i586-mandrake-linux-gnu/3.4.1/../../../../include/c++/
3.4.1/bits/stl_algobase.h:358: instantiated from `_OutputIterator
std::copy(_InputIterator, _InputIterator, _OutputIterator) [with
_InputIterator = MyCont::Iterator, _OutputIterator = char*]'
container.cpp:41: instantiated from here
/usr/lib/gcc/i586-mandrake-linux-gnu/3.4.1/../../../../include/c++/
3.4.1/bits/stl_iterator_base_types.h:129: error: no type named
`iterator_category' in `class MyCont::Iterator'

....more ot those errors about value_type and all such things.

Do i have to provide my implementation with these types?
If yes, what about iterator_categoy?
What about the simple char* parameters given to the std::copy
algorithm ? why are they ok?

thank you all,
vasilis.

 
Reply With Quote
 
 
 
 
Victor Bazarov
Guest
Posts: n/a
 
      06-15-2007
vasili wrote:
> I have a simple issue.




> I defined a custom container, that encloses a std::list, which in turn
> holds objects that are a simple abstraction of a six position array.
>
> Now, i would like to serialize the whole newly-defined container, in
> order to copy the contents to another array. So i thought to define an
> iterator which represented a "pointer" to the container's data. But,
> when i feed these iterators to std::copy the compiler complains about
> a lot of types which are defined when a std::iterator is instanced.


Since you want to use standard algorithm, it _may_ require that you
specialize 'iterator_traits' for your custom iterator.

>
> the code:
>
> //i leave all unnecessary stuff out just to be clear
> #include <list>
>
> using namespace std;
>
> class SixBytes{
> public: //i don't trash the example with any accessor methods
> char m_data[6];
> };
>
> class MyCont{
> list<SixBytes> m_list;
> public:
> class Iterator{
> const MyCont& m_cont;
> int m_index;
> public:
> Iterator(const MyCont& cnt, int index=0):m_cont(cnt),
> m_index(index){}
> Iterator operator++(int){//postfix? just placed this
> and the following methods to be "complete" //
> w.r.t. the requirements of the std::copy algorithm and to this example
> Iterator ret(*this);
> m_index++;
> return ret;
> }
> Iterator& operator++(){//prefix?
> m_index++;
> return *this;
> }
> char operator*(){
> //...return the byte that corresponds to the
> position m_
> index
> }
> };
>
> inline Iterator begin() const{ return Iterator(*this); }//the
> start of the serialization
> inline const Iterator end() const { return Iterator(*this,
> m_list.size()*6); }//it's end
> MyCont(){ m_list.push_back(SixBytes());
> m_list.push_back(SixBytes());}
> };
>
> int main(){
> char data[13];
> data[0] = 2;
> MyCont m;
> std::copy(m.begin(), m.end(), data+1);
> }//example ends here
>
> giving this to the compiler i get this:
>
> /usr/lib/gcc/i586-mandrake-linux-gnu/3.4.1/../../../../include/c++/
> 3.4.1/bits/stl_iterator_base_types.h: In instantiation of
> `std::iterator_traits<MyCont::Iterator>':

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
That's the implicit specialisation the compiler attempts. And fails.

> [..]
>
> Do i have to provide my implementation with these types?


Yes, if you want your code to compile.

> If yes, what about iterator_categoy?


Yes

> What about the simple char* parameters given to the std::copy
> algorithm ? why are they ok?


Yes, because the standard library most likely already contains the
specialisation of 'itetator_traits' for built-in pointer types.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask


 
Reply With Quote
 
 
 
 
Roland Pibinger
Guest
Posts: n/a
 
      06-15-2007
On Fri, 15 Jun 2007 07:18:55 -0700, vasili wrote:
>I have a simple issue.


If it were simple it wouldn't be C++.

>I defined a custom container, that encloses a std::list, which in turn
>holds objects that are a simple abstraction of a six position array.


AFAICS, you want to iterate over the list _and_ the 'six position
array' with a new iterator (not just re-use the
list<SixBytes>::iterator). In this case you need to define your own
iterator with all required typedefs and functions. Look for 'custom
STL iterator', e.g.
http://www.stanford.edu/class/cs107l...-Iterators.pdf
http://www.oonumerics.org/tmpw00/becker.html


--
Roland Pibinger
"The best software is simple, elegant, and full of drama" - Grady Booch
 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      06-16-2007
On Jun 15, 5:02 pm, "Victor Bazarov" <v.Abaza...@comAcast.net> wrote:
> vasili wrote:
> > I have a simple issue.


>


It takes a complicated language to solve complicated
problems.

> > I defined a custom container, that encloses a std::list, which in turn
> > holds objects that are a simple abstraction of a six position array.


> > Now, i would like to serialize the whole newly-defined container, in
> > order to copy the contents to another array. So i thought to define an
> > iterator which represented a "pointer" to the container's data. But,
> > when i feed these iterators to std::copy the compiler complains about
> > a lot of types which are defined when a std::iterator is instanced.


> Since you want to use standard algorithm, it _may_ require that you
> specialize 'iterator_traits' for your custom iterator.


He must do something to ensure that iterator_traits<Iterator>
contains the proper typedefs. The generic implementation of
this template supposes that there are corresponding typedef's in
the Iterator class; the standard library also contains a partial
specialization for pointers (since pointers obviously don't
contain the necessary typedef's). He can thus either provide a
custom specialization, with the necessary typedef's, or put the
typedef's in his class. The latter is the classical solution,
and the standard offers a class template, std::iterator, to help
here. All he has to do is have his iterator derive (publicly)
from the appropriate instantiation of std::iterator, and it
should suffice.

--
James Kanze (Gabi Software) email:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
List iterator assignment fails, assert iterator not dereferencable David Bilsby C++ 5 10-09-2007 02:05 PM
What makes an iterator an iterator? Steven D'Aprano Python 28 04-20-2007 03:34 AM
Difference between Java iterator and iterator in Gang of Four Hendrik Maryns Java 18 12-22-2005 05:14 AM
How to convert from std::list<T*>::iterator to std::list<const T*>::iterator? PengYu.UT@gmail.com C++ 6 10-30-2005 03:31 AM
Iterator doubts, Decision on Iterator usage greg C++ 6 07-17-2003 01:26 PM



Advertisments
 



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