C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

the FOREACH macro

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
Guest






PostPosted: Sun Dec 31, 2006 12:04 am    Post subject: the FOREACH macro Reply with quote



Hi,

I would like to do something like this, which is the WISH case:

Quote:
typedef map<int, double> hash;
hash a;
// ...
FOREACH(a, key, value, hash)
std::cout << key << "->" << value << "\n";

I already can do something similar, which is the ALREADY-HAVE case:

Quote:
FOREACH(hash, i, hash)
std::cout << i->first << "->" << i->second << "\n";

with a macro that I defined this way (inspired by the iteration macros
in the Boost Graph Library):

Quote:
#define FOREACH(MNAME, INAME, MapType) \
for (MapType::iterator \
INAME = MNAME.begin(); INAME != MNAME.end(); ++INAME)

The complete source code for the example above is at the bottom of this
message.

You may rightfully argue that this macro makes little sense, because
you can just have a regular loop there. However, in my real code
(what I gave you here is just a show case) there are two loops and I
want to put then into a macro.

Now, the problem is that I can't declare in the for-loop the variables
key and value as shown in the WISH case. I don't have this problem in
the ALREADY-HAVE case, becasue I only have to declare an iterator.

Thanks for reading. Any ideas how to get closer to my WISH case?


Thanks & best,
Irek

*********************************************

#include <iostream>
#include <map>

#define FOREACH(MNAME, INAME, MapType) \
for (MapType::iterator \
INAME = MNAME.begin(); INAME != MNAME.end(); ++INAME)

using namespace std;

typedef map<int, double> hash;

int main()
{
hash a;

a[0] = 1.71;
a[1] = 3.14;

FOREACH(a, i, hash)
cout << i->first << "->" << i->second << "\n";

return 0;
}


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Guest






PostPosted: Mon Jan 01, 2007 2:21 am    Post subject: Re: the FOREACH macro Reply with quote



irek.szczesniak (AT) gmail (DOT) com wrote:

Quote:
Hi,

I would like to do something like this, which is the WISH case:

typedef map<int, double> hash;
hash a;
// ...
FOREACH(a, key, value, hash)
std::cout << key << "->" << value << "\n";

Hi,

It might be something like this?

#define FOREACH(A, Key, Value, Hash) \
for (Hash::iterator INAME = A.begin(); INAME != A.end(); ++INAME) \
for (bool continue_ = true; continue_;) \
for (Hash::key_type Key = INAME->first; continue_;) \
for (Hash::mapped_type Value = INAME->second;
continue_; continue_ = false) \
/**/

I of course recommand to use BOOST_FOREACH Smile
http://www.boost-consulting.com/vault/index.php?directory=Algorithms

--
Shunsuke Sogame


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Guest






PostPosted: Mon Jan 01, 2007 9:43 pm    Post subject: Re: the FOREACH macro Reply with quote



Hi John,

Thanks for your input. However, using std::for_each complicates things
too much: I want to see beneath the FOREACH loop what's happening in my
code and not to read the function object.


Best,
Irek

John L Fjellstad wrote:

Quote:
irek.szczesniak (AT) gmail (DOT) com writes:

Hi,

I would like to do something like this, which is the WISH case:

typedef map<int, double> hash;
hash a;
// ...
FOREACH(a, key, value, hash)
std::cout << key << "->" << value << "\n";

Would it be easier to use for_each()?

Something like this:
#########
#include <iostream
#include <map
#include <cstdlib

struct PrintOut
{
private:
int key_;

public:
PrintOut( int key ) : key_(key) {}

void operator() ( const std::pair<int, double>& p )
{
if (key_ == p.first)
std::cout << p.first << "->" << p.second << "\n";
}
};

int
main()
{
std::map<int, double> a;

a.insert( std::make_pair<int,double>(0, 1.71) );
a.insert( std::make_pair<int,double>(1, 3.14) );

std::for_each( a.begin(), a.end(), PrintOut(1) );

return EXIT_SUCCESS;
}
#########


--
John L. Fjellstad
web: http://www.fjellstad.org/ Quis custodiet ipsos custodes
Replace YEAR with current four digit year
--

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Guest






PostPosted: Mon Jan 01, 2007 9:43 pm    Post subject: Re: the FOREACH macro Reply with quote

Hi Shunsuke,

This is awesome! It's interesting how you introduced the local loop
variables Key and Value. It's a nice trick. Naturally, there is the
performance penalty for this trick: the continue_ variable is
initialized, then evaluated twice, and then a value is assigned.
Nonetheless, I'll pay this penalty just to have a more readable code.

And the BOOST_FOREACH looks interesting, and I'll look closer at it.


Best,
Irek

pstade.mb (AT) gmail (DOT) com wrote:

Quote:
irek.szczesniak (AT) gmail (DOT) com wrote:

Hi,

I would like to do something like this, which is the WISH case:

typedef map<int, double> hash;
hash a;
// ...
FOREACH(a, key, value, hash)
std::cout << key << "->" << value << "\n";

Hi,

It might be something like this?

#define FOREACH(A, Key, Value, Hash) \
for (Hash::iterator INAME = A.begin(); INAME != A.end(); ++INAME) \
for (bool continue_ = true; continue_;) \
for (Hash::key_type Key = INAME->first; continue_;) \
for (Hash::mapped_type Value = INAME->second;
continue_; continue_ = false) \
/**/

I of course recommand to use BOOST_FOREACH Smile
http://www.boost-consulting.com/vault/index.php?directory=Algorithms

--
Shunsuke Sogame
--

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Daniel K. O.
Guest





PostPosted: Wed Jan 03, 2007 12:49 am    Post subject: Re: the FOREACH macro Reply with quote

irek.szczesniak (AT) gmail (DOT) com escreveu:
Quote:
This is awesome! It's interesting how you introduced the local loop
variables Key and Value. It's a nice trick. Naturally, there is the
performance penalty for this trick: the continue_ variable is
initialized, then evaluated twice, and then a value is assigned.
Nonetheless, I'll pay this penalty just to have a more readable code.

Even if C++ haters say otherwise, the C++ compilers whe have today are
much more than "high-level assemblers".

I just compiled that code with "gcc -O1" (4.1.1) and checked the
generated assembly. There's nothing there that ressembles any variable
other than the iterator itself (tested with a std::map).

I doubt that any mainstream compiler will fail to do such basic
optimization.


--
Daniel K. O.

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.