473,403 Members | 2,183 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,403 software developers and data experts.

Concerning STL iterators

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

Nov 21 '06 #1
8 1572
pv******@gmail.com 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.

Nov 21 '06 #2
pv******@gmail.com 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

Nov 21 '06 #3
pv******@gmail.com 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.

Nov 21 '06 #4
pv******@gmail.com 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)
Nov 21 '06 #5

Mathias Gaunard wrote:
pv******@gmail.com 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

Nov 21 '06 #6

pv******@gmail.com 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
}
}

Nov 21 '06 #7
Salt_Peter wrote:
Container(const Container& copy)
{
std::swap(copy.themap, themap);

Copying is the same as swapping now?
Nov 21 '06 #8

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.

Nov 21 '06 #9

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

Similar topics

10
by: Steven Bethard | last post by:
So, as I understand it, in Python 3000, zip will basically be replaced with izip, meaning that instead of returning a list, it will return an iterator. This is great for situations like: zip(*)...
18
by: deancoo | last post by:
I have gotten into the habit of often using copy along with an insert iterator. There are scenarios where I process quite a lot of data this way. Can someone give me a general feel as to how much...
1
by: Marcin Kaliciñski | last post by:
template<class RanAccIt> void some_algorithm(RanAccIt begin, RanAccIt end) { // this algorithm involves calling std::lexicographical_compare // on range [begin, end), and on reverse of this range...
3
by: codefixer | last post by:
Hello, I am trying to understand if ITERATORS are tied to CONTAINERS. I know the difference between 5 different or 6(Trivial, on SGI). But what I fail to understand is how can I declare all 5...
8
by: babak | last post by:
Hi everyone I have a problem with Iterators and containers in STL that hopefully someone can help me with. This is what I try to do: I have an associative (map) container and I have a...
24
by: Lasse Vågsæther Karlsen | last post by:
I need to merge several sources of values into one stream of values. All of the sources are sorted already and I need to retrieve the values from them all in sorted order. In other words: s1 = ...
2
by: ma740988 | last post by:
typedef std::vector < std::complex < double > > complex_vec_type; // option1 int main() { complex_vec_type cc ( 24000 ); complex_vec_type dd ( &cc, &cc ); } versus
90
by: John Salerno | last post by:
I'm a little confused. Why doesn't s evaluate to True in the first part, but it does in the second? Is the first statement something different? False print 'hi' hi Thanks.
18
by: desktop | last post by:
1) I have this code: std::list<intmylist; mylist.push_back(1); mylist.push_back(2); mylist.push_back(3); mylist.push_back(4);
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
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: 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
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...
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
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
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,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

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.