473,791 Members | 3,122 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

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<int myvector (myints,myints+ 10);
std::vector<int >::iterator forward_iterato r = myvector.end();

I can still type "--forward_iterato r" 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_iterato rs, 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 1863
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<int myvector (myints,myints+ 10);
std::vector<int >::iterator forward_iterato r = myvector.end();

I can still type "--forward_iterato r" 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_iterato rs, 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<int myvector (myints,myints+ 10);
std::vector<int >::iterator forward_iterato r = myvector.end();

I can still type "--forward_iterato r" 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_iterato r 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<typena me 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_iterato rs, 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<in tmyvector (myints,myints+ 10);
std::vector<in t>::iterator forward_iterato r = myvector.end();

I can still type "--forward_iterato r" 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_iterato r 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<typena me 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 MyContainerIter ator
{
public:
bool operator==(cons t MyContainerIter ator&) const;
const MyContainerIter ator & operator==(cons t MyContainerIter ator&);
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 MyContainerIter ator iterator;

iterator begin();
iterator end();
}

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

MyContainer::it erator 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 MyContainerIter ator
{
public:
bool operator==(cons t MyContainerIter ator&) const;
const MyContainerIter ator & operator==(cons t MyContainerIter ator&);
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 MyContainerIter ator iterator;

iterator begin();
iterator end();
}

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

MyContainer::it erator 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.comwr ote:
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<int myvector (myints,myints+ 10);
std::vector<int >::iterator forward_iterato r = myvector.end();
std::vector<int >::const_iterat or
>
I can still type "--forward_iterato r" 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_iterato rs, 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<in tmyvector (myints,myints+ 10);
std::vector<in t>::iterator forward_iterato r = myvector.end();

I can still type "--forward_iterato r" 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>::it erator pos;
// vector::iterato r 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<i ntmyvector (myints,myints+ 10);
std::vector<i nt>::iterator forward_iterato r = myvector.end();

I can still type "--forward_iterato r" 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

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

Similar topics

38
3693
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 mentioned: I characterized one way of looking at languages in this way: a lot of them are either the agglutination of features or they're a crystallization of style. Languages such as APL, Lisp, and Smalltalk are what you might call style...
26
1514
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 Iterator { public : typedef typename Set::value_type T; typedef typename Set::iterator SetIterator; Iterator(Set& container, const SetIterator& it);
13
2541
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;} }; int main() { int arr = {1, 2, 3}; set<int,Asc> asc(arr, arr+3); set<int,Des>::iterator beg = asc.begin(); // set<int,Des>::iterator end = asc.end(); // copy(beg, end, ostream_iterator<int>(cout,...
14
4880
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 to an iterator method (one returning IEnumerable). I WOULD like to do this for transformative operations on a collection. I realize the need to lock target, etc. Does anyone know how to handle 'writable iterators' in C# 2?
4
6379
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 what it does.): vector<int> int_vector; vector<int>::iterator i, j; for (i = int_vector.begin (); i != int_vector.end (); i++)
6
3719
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 they point to. Example -- if L is a list and Li = L.end(), and you call L.push_back(something), how do you know whether Li will still point to the list's end, or whether it will point to the something? I tried this program in Microsoft VC++ 6.0...
21
5724
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 classes by inheriting from it, ie. class my_bidirectional_iterator : public bidirectional_iterator<double> { ... };
16
2590
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 totally_isolated(Iterator& it) { //how do I find out if it points to the end node? }
22
1578
by: =?gb2312?B?wNbA1rTzzOzKpg==?= | last post by:
windows xp, visual studio 2005 ---------------------------------------------------------------------------------------------------------------------------------- #include <iostream> #include <map> using namespace std; int main() { map<int, int>::iterator it = 0; if( it != 0 ) //break point,
0
9512
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10419
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, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10201
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 tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
9987
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 protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
6770
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5424
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5552
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4100
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
3
2910
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.