Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Concerning STL iterators

Reply
Thread Tools

Concerning STL iterators

 
 
pvonnied@gmail.com
Guest
Posts: n/a
 
      11-21-2006
Hi,

Once more a question (sorry for the different e-mail addresses [in
regard
to my other posts], here @ work we have to use Google to post to
newsgroups):

If I use an iterator, say from std::map, I initialize it like so:
<--- --->
std::map<int, myClass*> myCollection;
std::map<int, myClass*>::iterator it = myCollection.begin();
for(; it != myCollection.begin(); ++it) { // do something }
---><---

For which reasons C++ uses the syntax above (I guess
because we use templates) ? Why is it not possible to
use myCollection.iterator it = myCollection.begin(); like
a kind of an inner class (Java style...)?

That would eliminate the need to retype std::map<int, myClass*>...
just to get an iterator. I know that I could use a typedef...

Binary regards (as one suggested in stead of my Brgds tag ),
Peter

 
Reply With Quote
 
 
 
 
mlimber
Guest
Posts: n/a
 
      11-21-2006
http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:
> If I use an iterator, say from std::map, I initialize it like so:
> <--- --->
> std::map<int, myClass*> myCollection;


You probably want to use some sort of smart pointer rather than a bald
pointer for exception-safety and ease of use (see
http://www.artima.com/cppsource/bigtwo.html).

> std::map<int, myClass*>::iterator it = myCollection.begin();
> for(; it != myCollection.begin(); ++it) { // do something }


You probably meant myCollection.end() on the last line. The more
idiomatic way is:

typedef std::map<int, myClass*>::iterator Iter;
const Iter end = myCollection.end();
for( Iter it=myCollection.begin(); it != end; ++it)
{ // do something }

or

typedef std::map<int, myClass*>::iterator Iter;
for( Iter it=myCollection.begin(), end = myCollection.end(); it !=
end; ++it)
{ // do something }

or even

for_each( myCollection.begin(), myCollection.end(), /*something*/ );

> ---><---
>
> For which reasons C++ uses the syntax above (I guess
> because we use templates) ?


Which syntax in particular?

> Why is it not possible to
> use myCollection.iterator it = myCollection.begin(); like
> a kind of an inner class (Java style...)?


Because this is not Java? It's because C++ has a distinct member access
operator (.) and a scope operator (: -- not to mention ->. For why
this is so, you'll want to consult Stroustrup's _Design and Evolution
of C++_ (which I'm not sure actually discusses it) or just deal with
it.

> That would eliminate the need to retype std::map<int, myClass*>...
> just to get an iterator. I know that I could use a typedef...


If you know the answer, stop being lazy.

Cheers! --M

 
Reply With Quote
 
 
 
 
Mathias Gaunard
Guest
Posts: n/a
 
      11-21-2006
(E-Mail Removed) wrote:

> Why is it not possible to
> use myCollection.iterator it = myCollection.begin(); like
> a kind of an inner class (Java style...)?


Because member types are static members and don't depend on the bound
object.


> That would eliminate the need to retype std::map<int, myClass*>...
> just to get an iterator.


This will be removed in C++0x with the new type interence related keywords.

 
Reply With Quote
 
dasjotre
Guest
Posts: n/a
 
      11-21-2006
(E-Mail Removed) wrote:
> Hi,
>
> Once more a question (sorry for the different e-mail addresses [in
> regard
> to my other posts], here @ work we have to use Google to post to
> newsgroups):
>
> If I use an iterator, say from std::map, I initialize it like so:
> <--- --->
> std::map<int, myClass*> myCollection;
> std::map<int, myClass*>::iterator it = myCollection.begin();
> for(; it != myCollection.begin(); ++it) { // do something }
> ---><---
>
> For which reasons C++ uses the syntax above (I guess
> because we use templates) ? Why is it not possible to
> use myCollection.iterator it = myCollection.begin(); like
> a kind of an inner class (Java style...)?
>


:: is a scope operator and it works on types
or namespaces, not objects. Dot operator
works on objects (instances).

in C++ you can have a construct like this

struct C
{
// type
struct inner_C {};
// member with the same name
int inner_C;
};

so

C::inner_C

references the type inner_C and

C c;
c.inner_C

references an int member inner_C of object c.

Why is it that way? Because standard says so

> That would eliminate the need to retype std::map<int, myClass*>...
> just to get an iterator. I know that I could use a typedef...
>


typedef is the solution.

 
Reply With Quote
 
Pete Becker
Guest
Posts: n/a
 
      11-21-2006
(E-Mail Removed) wrote:
> Hi,
>
> Once more a question (sorry for the different e-mail addresses [in
> regard
> to my other posts], here @ work we have to use Google to post to
> newsgroups):
>
> If I use an iterator, say from std::map, I initialize it like so:
> <--- --->
> std::map<int, myClass*> myCollection;
> std::map<int, myClass*>::iterator it = myCollection.begin();
> for(; it != myCollection.begin(); ++it) { // do something }
> ---><---
>
> For which reasons C++ uses the syntax above (I guess
> because we use templates) ? Why is it not possible to
> use myCollection.iterator it = myCollection.begin(); like
> a kind of an inner class (Java style...)?
>


Because Java's iterators are different from C++'s iterators. In C++, an
iterator designates one end of a range of elements. You use a pair of
iterators to designate a range: one to mark the beginning, and one to
mark the end. That gives you a great deal more flexibility than
combining both ends into a single object.

> That would eliminate the need to retype std::map<int, myClass*>...
> just to get an iterator. I know that I could use a typedef...
>


Ordinarily, iterators are passed to algorithms:

std::map<int, myClass*> myCollection;
// do something to populate myCollection
algorithm(myCollection.begin(), myCollection.end());

Where algorithm is a template function that takes two iterators of the
same type:

template <class Iter>
void algorithm(Iter first, Iter last)
{
while (first != last)
do_something_with *first++;
}

Code that creates auto objects that hold iterators is non-idiomatic, so
it tends to be more awkward. But if you can't hoist that for loop out
into a separate function, then you have to write the name of the
iterator's type.

There's help coming, though: in C++0x there will probably be automatic
type detection, so that you can define a local variable whose type is
the same as its initializer, without having to write the type explicitly.

--

-- Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com)
Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." (www.petebecker.com/tr1book)
 
Reply With Quote
 
kwikius
Guest
Posts: n/a
 
      11-21-2006

Mathias Gaunard wrote:
> (E-Mail Removed) wrote:
>
> > Why is it not possible to
> > use myCollection.iterator it = myCollection.begin(); like
> > a kind of an inner class (Java style...)?

>
> Because member types are static members and don't depend on the bound
> object.
>
>
> > That would eliminate the need to retype std::map<int, myClass*>...
> > just to get an iterator.

>
> This will be removed in C++0x with the new type interence related keywords.


I got a feeling that progress on that stalled though it sure will be a
bit sad if that doesnt happen.

regards
Andy Little

 
Reply With Quote
 
Salt_Peter
Guest
Posts: n/a
 
      11-21-2006

(E-Mail Removed) wrote:
> Hi,
>
> Once more a question (sorry for the different e-mail addresses [in
> regard
> to my other posts], here @ work we have to use Google to post to
> newsgroups):
>
> If I use an iterator, say from std::map, I initialize it like so:
> <--- --->
> std::map<int, myClass*> myCollection;
> std::map<int, myClass*>::iterator it = myCollection.begin();
> for(; it != myCollection.begin(); ++it) { // do something }
> ---><---
>
> For which reasons C++ uses the syntax above (I guess
> because we use templates) ? Why is it not possible to
> use myCollection.iterator it = myCollection.begin(); like
> a kind of an inner class (Java style...)?
>
> That would eliminate the need to retype std::map<int, myClass*>...
> just to get an iterator. I know that I could use a typedef...
>
> Binary regards (as one suggested in stead of my Brgds tag ),
> Peter


Whats preventing you from doing so? Since this is a std::map?
Its your choice if you choose to expose iterators or to embed an
iterator class.
You only need to insure any exposed iterator is reset appropriately.
Note that resetting iterators is not neccessarily a costly operation
since you could, say, provide an overloaded swap(...) member function
that works with other containers.

#include <iostream>
#include <map>

template< typename T, typename P >
class Container
{
typedef typename std::map< const T, const P* const > MapType;
typedef typename MapType::iterator IterType;
MapType themap;
public:
IterType iter_begin;
IterType iter_end;
IterType iter;
// lifecycle
Container() : themap(),
iter_begin(themap.begin()),
iter_end(themap.end()),
iter()
{
}
Container(const Container& copy)
{
std::swap(copy.themap, themap);
iter_begin = themap.begin();
iter_end = themap.end();
}
void insert(const T& r_t, const P* const ptr_m)
{
themap.insert(std::make_pair(r_t, ptr_m));
iter_begin = themap.begin();
iter_end = themap.end();
}
};

struct MyClass
{
int n;
};

int main()
{
const MyClass array[] = {{0},{1},{2},{3},{4}};
Container< int, MyClass > container;
for( size_t i = 0; i < sizeof(array)/sizeof(MyClass); ++i)
{
container.insert(static_cast<int>(i), &array[i]);
}
for( container.iter = container.iter_begin;
container.iter != container.iter_end;
++container.iter )
{
// do whatever
}
}

 
Reply With Quote
 
Mathias Gaunard
Guest
Posts: n/a
 
      11-21-2006
Salt_Peter wrote:

> Container(const Container& copy)
> {
> std::swap(copy.themap, themap);



Copying is the same as swapping now?
 
Reply With Quote
 
Salt_Peter
Guest
Posts: n/a
 
      11-21-2006

Mathias Gaunard wrote:
> Salt_Peter wrote:
>
> > Container(const Container& copy)
> > {
> > std::swap(copy.themap, themap);

>
>
> Copying is the same as swapping now?


I'm brain-dead today.

 
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
plain iterators and reverse iterators on vector subramanian100in@yahoo.com, India C++ 10 08-08-2009 08:28 AM
Iterators and reverse iterators Marcin Kaliciński C++ 1 05-08-2005 09:58 AM
Iterators and containers STL Merlin C++ 4 04-30-2004 09:37 PM
STL iterators Rusty C++ 1 11-29-2003 12:42 AM
STL iterators and the std namespace onion_skin C++ 9 06-26-2003 12:49 AM



Advertisments