473,396 Members | 2,011 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

How to gurantee iterator behavior?

I have read about input, output forward etc iterators. But if I make the
following:

int myints[] = {1,2,3,4,5,1,2,3,4,5};
std::vector<intmyvector (myints,myints+10);
std::vector<int>::iterator forward_iterator = myvector.end();

I can still type "--forward_iterator" eventhough "--it" is illegal on
forward iterators.

Are there some way to specify an iterator so the compiler will give
errors if used incorrectly, like when using the keyword "const" on a
variable?

I also read that find_end uses forward_iterators, but as I understand
they provide sequential read-write access. I don't see why the write
access is needed, would an input_iterator (read-only) not be more
appropriate since find only returns unchanged info?
Apr 25 '07 #1
10 1834
desktop wrote:
I have read about input, output forward etc iterators. But if I make the
following:

int myints[] = {1,2,3,4,5,1,2,3,4,5};
std::vector<intmyvector (myints,myints+10);
std::vector<int>::iterator forward_iterator = myvector.end();

I can still type "--forward_iterator" eventhough "--it" is illegal on
forward iterators.
std::vector<T>::iterator does support --.
>
Are there some way to specify an iterator so the compiler will give
errors if used incorrectly, like when using the keyword "const" on a
variable?
I suppose you can create a class that is an iterator and override
operator--. There is some work on a thing called "C++ Concepts" that
may be what you're looking for. I personally don't set the cost/benefit
ratio working out but I may be wrong on this one.
>
I also read that find_end uses forward_iterators, but as I understand
they provide sequential read-write access. I don't see why the write
access is needed, would an input_iterator (read-only) not be more
appropriate since find only returns unchanged info?
You can send a const_iterator to find_end.
Apr 25 '07 #2
desktop wrote:
I have read about input, output forward etc iterators. But if I make the
following:

int myints[] = {1,2,3,4,5,1,2,3,4,5};
std::vector<intmyvector (myints,myints+10);
std::vector<int>::iterator forward_iterator = myvector.end();

I can still type "--forward_iterator" eventhough "--it" is illegal on
forward iterators.
that's because, if you see the documentation for the class vector, you
will discover that the vector iterator is a random iterator, that is, it
implements the operators ++, --, ==, &, <, +=, -=, +, -, [] (if I
haven't forgot any). forward_iterator is just the name of your variable :)
Are there some way to specify an iterator so the compiler will give
errors if used incorrectly, like when using the keyword "const" on a
variable?
it's not needed. For example, if they tell you that the function

template<typename iterator>
foo(iterator i);

requires a bidirectional iterator, it's because inside of foo both the
operators ++ and -- will be used. If you provide it with a forward
iterator, the compiler will complain, not finding any operator-- for
that class.

I also read that find_end uses forward_iterators, but as I understand
they provide sequential read-write access. I don't see why the write
access is needed, would an input_iterator (read-only) not be more
appropriate since find only returns unchanged info?
this would be a const_iterator. The same, but read only.

Regards,

Zeppe
Apr 25 '07 #3
Zeppe wrote:
desktop wrote:
>I have read about input, output forward etc iterators. But if I make the
following:

int myints[] = {1,2,3,4,5,1,2,3,4,5};
std::vector<intmyvector (myints,myints+10);
std::vector<int>::iterator forward_iterator = myvector.end();

I can still type "--forward_iterator" eventhough "--it" is illegal on
forward iterators.

that's because, if you see the documentation for the class vector, you
will discover that the vector iterator is a random iterator, that is, it
implements the operators ++, --, ==, &, <, +=, -=, +, -, [] (if I
haven't forgot any). forward_iterator is just the name of your variable :)
>Are there some way to specify an iterator so the compiler will give
errors if used incorrectly, like when using the keyword "const" on a
variable?

it's not needed. For example, if they tell you that the function

template<typename iterator>
foo(iterator i);

requires a bidirectional iterator, it's because inside of foo both the
operators ++ and -- will be used. If you provide it with a forward
iterator, the compiler will complain, not finding any operator-- for
that class.
I am a bit confused. How will the compiler complain if a forward
iterator is just a variable name? The only way I can get it to report an
error is if I make my own class "class ForwarIterator" where I somehow
make it illegal to use "--".
Apr 25 '07 #4
desktop wrote:
I am a bit confused. How will the compiler complain if a forward
iterator is just a variable name?
it won't complain.
The only way I can get it to report an
error is if I make my own class "class ForwarIterator" where I somehow
make it illegal to use "--".
Well, is not necessary to make the use of operator-- forbidden. It's
enough not to define it. Example, you write a very strange container
that for some really good reason ant to provide only the forward access
to the elements. You decide to implement the iterators for your
container, because it's a good and flexible way to access it (maybe is
not possible to access it like a normal vector, with []).

The you will write:

class MyContainerIterator
{
public:
bool operator==(const MyContainerIterator&) const;
const MyContainerIterator & operator==(const MyContainerIterator&);
MyType& operator*();
};

where MyType is the type of the elements of you container. The
implementation of the iterator will be more or less difficult depending
on your container.

and then, in your container:

class MyContainer
{
public:
typedef MyContainerIterator iterator;

iterator begin();
iterator end();
}

ok, now your container has got a forward iterator. When you want to use
it, you will define

MyContainer::iterator foo = mycont.begin();

you will be able to use it in all the stl functions that accept a
forward iterator, but if you put in some function that accept beckward
iterators, for example, the compiler will try to use the operator-- on
your Iterator class, and will complain because it haven't got it.

Regards,

Zeppe
Apr 25 '07 #5
Zeppe wrote:
desktop wrote:
>I am a bit confused. How will the compiler complain if a forward
iterator is just a variable name?

it won't complain.
>The only way I can get it to report an
error is if I make my own class "class ForwarIterator" where I somehow
make it illegal to use "--".

Well, is not necessary to make the use of operator-- forbidden. It's
enough not to define it. Example, you write a very strange container
that for some really good reason ant to provide only the forward access
to the elements. You decide to implement the iterators for your
container, because it's a good and flexible way to access it (maybe is
not possible to access it like a normal vector, with []).

The you will write:

class MyContainerIterator
{
public:
bool operator==(const MyContainerIterator&) const;
const MyContainerIterator & operator==(const MyContainerIterator&);
MyType& operator*();
};

where MyType is the type of the elements of you container. The
implementation of the iterator will be more or less difficult depending
on your container.

and then, in your container:

class MyContainer
{
public:
typedef MyContainerIterator iterator;

iterator begin();
iterator end();
}

ok, now your container has got a forward iterator. When you want to use
it, you will define

MyContainer::iterator foo = mycont.begin();

you will be able to use it in all the stl functions that accept a
forward iterator, but if you put in some function that accept beckward
iterators, for example, the compiler will try to use the operator-- on
your Iterator class, and will complain because it haven't got it.

Regards,

Zeppe

Ok but is there not a class in the STL that defines this kind of
behavior for an iterator already?

Seems confusing that the iterators mentioned at:

http://www.cppreference.com/iterators.html

has different names but you can use the same operators on them. And the
only way to make them different are by making your own classes as your
example above.
Apr 25 '07 #6
desktop wrote:
Ok but is there not a class in the STL that defines this kind of
behavior for an iterator already?
no. At the end, since the real behaviour of the operators depends on
your specific container, the only thing that could be defined would be
some virtual function to be overloaded. Useless, since as I shown you if
you don't define the operators, the compiler will complain anyway, less
flexible, because for example you coudn't construct your vector from
int* as you did, and much less performing (and the iterators have to be
fast).
Seems confusing that the iterators mentioned at:

http://www.cppreference.com/iterators.html

has different names but you can use the same operators on them.
those names are not related to any class. It's just a categorization.
And the
only way to make them different are by making your own classes as your
example above.
well, the type of an iterator is defined only by the methods that it
supports. If your class is a forward iterator, has to support ++,==,*,
if it supportas also -- is not a forward iterator anymore, is a
bidirectional one. This is the template conceptual philosophy, sometimes
referred as "duck typing":

"When I see a bird that walks like a duck and swims like a duck and
quacks like a duck, I call that bird a duck."

In the iterators case, it would be:

"When I see an object that increments like a forward iterator and
decrements like a forward iterator and dereferences like a forward
iterator, I call that object a forward iterator."

Regards,

Zeppe
Apr 25 '07 #7
On 4ÔÂ25ÈÕ, ÏÂÎç4ʱ43·Ö, desktop <f...@sss.comwrote:
I have read about input, output forward etc iterators. But if I make the
following:

int myints[] = {1,2,3,4,5,1,2,3,4,5};
std::vector<intmyvector (myints,myints+10);
std::vector<int>::iterator forward_iterator = myvector.end();
std::vector<int>::const_iterator
>
I can still type "--forward_iterator" eventhough "--it" is illegal on
forward iterators.

Are there some way to specify an iterator so the compiler will give
errors if used incorrectly, like when using the keyword "const" on a
variable?

I also read that find_end uses forward_iterators, but as I understand
they provide sequential read-write access. I don't see why the write
access is needed, would an input_iterator (read-only) not be more
appropriate since find only returns unchanged info?

Apr 26 '07 #8
Gianni Mariani wrote:
desktop wrote:
>I have read about input, output forward etc iterators. But if I make
the following:

int myints[] = {1,2,3,4,5,1,2,3,4,5};
std::vector<intmyvector (myints,myints+10);
std::vector<int>::iterator forward_iterator = myvector.end();

I can still type "--forward_iterator" eventhough "--it" is illegal on
forward iterators.

std::vector<T>::iterator does support --.

On this page they pretty much conclude that bidirectional and
random_access iterators are the same thing:

// Random access iterators are bidirectional iterators that
// can access any point in the container.

http://anaturb.net/C/iter_example.ht...ccess_iterator

and that you declare them both with:
vector<int>::iterator pos;
// vector::iterator and deque::iterator
// are random access iterator types

So I don't understand that you write that

"std::vector<T>::iterator does support --."
Apr 28 '07 #9
On 2007-04-28 21:15, desktop wrote:
Gianni Mariani wrote:
>desktop wrote:
>>I have read about input, output forward etc iterators. But if I make
the following:

int myints[] = {1,2,3,4,5,1,2,3,4,5};
std::vector<intmyvector (myints,myints+10);
std::vector<int>::iterator forward_iterator = myvector.end();

I can still type "--forward_iterator" eventhough "--it" is illegal on
forward iterators.

std::vector<T>::iterator does support --.


On this page they pretty much conclude that bidirectional and
random_access iterators are the same thing:

// Random access iterators are bidirectional iterators that
// can access any point in the container.

http://anaturb.net/C/iter_example.ht...ccess_iterator
You can make a random access iterator "jump around", while a
bidirectional iterator can only move one step at a time.

Consider an collectionand an iterator it to the beginning of this
collection, then if you can use *(it + 3) to access the 4th element of
this collection the iterator is a random access iterator. If you have to
do it++; it++; it++; to get to the forth element it is at most a
bidirectional iterator.

--
Erik Wikström
Apr 28 '07 #10
On Apr 28, 9:15 pm, desktop <f...@sss.comwrote:
Gianni Mariani wrote:
desktop wrote:
I have read about input, output forward etc iterators. But if I make
the following:
int myints[] = {1,2,3,4,5,1,2,3,4,5};
std::vector<intmyvector (myints,myints+10);
std::vector<int>::iterator forward_iterator = myvector.end();
I can still type "--forward_iterator" eventhough "--it" is illegal on
forward iterators.
std::vector<T>::iterator does support --.
On this page they pretty much conclude that bidirectional and
random_access iterators are the same thing:
// Random access iterators are bidirectional iterators that
// can access any point in the container.
http://anaturb.net/C/iter_example.ht...ccess_iterator
You're quoting out of context. The very next sentence says that
"In a constant amount of time, one can move to any position in a
containerusing a random access iterator." Which is *not* true
for bidirectional iterators. (The wording in the page you quote
is somewhat loose, perhaps to try and make the text more easily
assimilable. The exact rule is that a random access iterator
meets all the constraints of a bidirectional iterator, and in
addition...)
and that you declare them both with:
vector<int>::iterator pos;
Both what? There is only one type in the declaration above, and
it meets to constraints of a random access iterator (which
includes the constraints of a bidirectional iterator, which
includes the constraints of a forward iterator, which includes
the constraints of an input iterator).
// vector::iterator and deque::iterator
// are random access iterator types
So I don't understand that you write that
"std::vector<T>::iterator does support --."
I don't understand what you don't understand. Random access
iterators must meet all of the constraints of bidirectional
iterators. One of those constraints is support for --.

--
James Kanze (Gabi Software) email: ja*********@gmail.com
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

Apr 29 '07 #11

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

38
by: Grant Edwards | last post by:
In an interview at http://acmqueue.com/modules.php?name=Content&pa=showpage&pid=273 Alan Kay said something I really liked, and I think it applies equally well to Python as well as the languages...
26
by: Michael Klatt | last post by:
I am trying to write an iterator for a std::set that allows the iterator target to be modified. Here is some relvant code: template <class Set> // Set is an instance of std::set<> class...
13
by: Dan Tsafrir | last post by:
is the following code standard? (cleanly compiles under g++-4.0.2): struct Asc { bool operator()(int a, int b) {return a < b;} }; struct Des { bool operator()(int a, int b) {return b > a;} };...
14
by: shawnk | last post by:
I searched the net to see if other developers have been looking for a writable iterator in C#. I found much discussion and thus this post. Currently (C# 2) you can not pass ref and out arguments...
4
by: Johan Pettersson | last post by:
Hi, I'm trying to "port" a project from VC++ 2003 to VC++ 2005 (Express Edition). This project contains the following code on several places (It is not exactly this code but a generalization of...
6
by: Jason S | last post by:
where is the behavior of list::iterator specified? I need to keep track of ranges of data, all I can figure out so far is that iterators are guaranteed to be valid unless you remove the elements...
21
by: T.A. | last post by:
I understand why it is not safe to inherit from STL containers, but I have found (in SGI STL documentation) that for example bidirectional_iterator class can be used to create your own iterator...
16
by: mailforpr | last post by:
How do I do that? The thing is, the only information I have about the iterator is the iterator itself. No container it is belonging to or anything. Like template<Iteratorvoid...
22
by: =?gb2312?B?wNbA1rTzzOzKpg==?= | last post by:
windows xp, visual studio 2005 ---------------------------------------------------------------------------------------------------------------------------------- #include <iostream> #include <map>...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.