
Hello, Boost::foreach is very useful for iterating over a sequence and doing something that depends only on the iterated element, e.g., <code> BOOST_FOREACH(const Foo &f, foos) cout << f.bar() << endl; </code> However, I often need to iterate over a sequence and do some operation that depends on both the iterated element and the iteration index. E.g., I would like something like <code> BOOST_FOREACH(size_t i, const Foo &f, foos) cout << "The bar of element " << i << " is " << f.bar() << endl; </code> Is there an easy way to do so? Thanks & Bye, TD

The Dude wrote:
Hello,
Boost::foreach is very useful for iterating over a sequence and doing something that depends only on the iterated element, e.g., <code> BOOST_FOREACH(const Foo &f, foos) cout << f.bar() << endl; </code>
However, I often need to iterate over a sequence and do some operation that depends on both the iterated element and the iteration index. E.g., I would like something like <code> BOOST_FOREACH(size_t i, const Foo &f, foos) cout << "The bar of element " << i << " is " << f.bar() << endl; </code>
Is there an easy way to do so?
Why not: int index = 0; BOOST_FOREACH(const Foo &f, foos) { // ... stuff ... ++index; } ? -- Eric Niebler BoostPro Computing http://www.boostpro.com

On Sun, Dec 13, 2009 at 11:51 PM, Eric Niebler
The Dude wrote:
Hello,
Boost::foreach is very useful for iterating over a sequence and doing something that depends only on the iterated element, e.g., <code> BOOST_FOREACH(const Foo &f, foos) cout << f.bar() << endl; </code>
However, I often need to iterate over a sequence and do some operation that depends on both the iterated element and the iteration index. E.g., I would like something like <code> BOOST_FOREACH(size_t i, const Foo &f, foos) cout << "The bar of element " << i << " is " << f.bar() << endl; </code>
Is there an easy way to do so?
Why not:
int index = 0;
BOOST_FOREACH(const Foo &f, foos) { // ... stuff ... ++index; }
?
-- Eric Niebler BoostPro Computing http://www.boostpro.com
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
Hello, Thanks for you answer. I'm not sure how to answer the "why not"? The code you write certainly will work, but so would the predecessor to BOOST_FOREACH in the first place, no? So here's my attempt: 1. For shorter loops, this changes 2 LOCs to 5. 2. For longer loops, the iteration code changes its meaning if it appears before the ++index or after. 3. The variable index has scope outside the loop. 4. Other people think so, e.g., the author's of D language http://en.wikipedia.org/wiki/D_(programming_language)#Example_1 It's true that none of these points is really a proof. Still, I'd be really happy to hack my own INDEX_FOREACH, but the 500+ LOCs of BOOST_FOREACH left me daunted. Thanks & Bye, TD

The Dude wrote:
Eric Niebler wrote:
Why not:
int index = 0;
BOOST_FOREACH(const Foo &f, foos) { // ... stuff ... ++index; }
?
Thanks for you answer. I'm not sure how to answer the "why not"? The code you write certainly will work, but so would the predecessor to BOOST_FOREACH in the first place, no? So here's my attempt: 1. For shorter loops, this changes 2 LOCs to 5.
So put it all on one line! Kidding. ;-)
2. For longer loops, the iteration code changes its meaning if it appears before the ++index or after. 3. The variable index has scope outside the loop. 4. Other people think so, e.g., the author's of D language http://en.wikipedia.org/wiki/D_(programming_language)#Example_1 It's true that none of these points is really a proof. Still, I'd be really happy to hack my own INDEX_FOREACH, but the 500+ LOCs of BOOST_FOREACH left me daunted.
This is true, but I'm not convinced. What value BOOST_FOREACH has comes primarily from its ability to simplify something that's already pretty darn simple -- a plain for(;;) loop. I strongly resist any effort to make BOOST_FOREACH more complicated, unless the wins are truly significant. In this case, I don't think they are. -- Eric Niebler BoostPro Computing http://www.boostpro.com

Eric Niebler wrote:
Why not:
int index = 0;
BOOST_FOREACH(const Foo &f, foos) { // ... stuff ... ++index; }
What value BOOST_FOREACH has comes primarily from its ability to simplify something that's already pretty darn simple -- a plain for(;;) loop. I strongly resist any effort to make BOOST_FOREACH more complicated, unless the wins are truly significant. In this case, I don't think they are.
Maybe this shouldn't be a BOOST_FOREACH feature at all. As with Python's
builtin enumerate() function, maybe what we want here is an iterator
adapter that dereferences to a std::pair

On Sun, Dec 13, 2009 at 6:41 PM, Nat Goodspeed
Eric Niebler wrote:
Why not:
int index = 0;
BOOST_FOREACH(const Foo &f, foos) { // ... stuff ... ++index; }
What value BOOST_FOREACH has comes primarily from its ability to simplify something that's already pretty darn simple -- a plain for(;;) loop. I strongly resist any effort to make BOOST_FOREACH more complicated, unless the wins are truly significant. In this case, I don't think they are.
Maybe this shouldn't be a BOOST_FOREACH feature at all. As with Python's builtin enumerate() function, maybe what we want here is an iterator adapter that dereferences to a std::pair
?
Ooo, that makes sense, as long as it can still be done quickly (ala the in index = 0; example above): BOOST_FOREACH(size_t i, const Foo &f, ENUMERATE(foos)) Or maybe: BOOST_FOREACH_ENUMERATE(size_t i, const Foo &f, foos)

On Sun, Dec 13, 2009 at 7:11 PM, OvermindDL1
On Sun, Dec 13, 2009 at 6:41 PM, Nat Goodspeed
wrote: Eric Niebler wrote:
Why not:
int index = 0;
BOOST_FOREACH(const Foo &f, foos) { // ... stuff ... ++index; }
What value BOOST_FOREACH has comes primarily from its ability to simplify something that's already pretty darn simple -- a plain for(;;) loop. I strongly resist any effort to make BOOST_FOREACH more complicated, unless the wins are truly significant. In this case, I don't think they are.
Maybe this shouldn't be a BOOST_FOREACH feature at all. As with Python's builtin enumerate() function, maybe what we want here is an iterator adapter that dereferences to a std::pair
? Ooo, that makes sense, as long as it can still be done quickly (ala the in index = 0; example above): BOOST_FOREACH(size_t i, const Foo &f, ENUMERATE(foos))
Or maybe: BOOST_FOREACH_ENUMERATE(size_t i, const Foo &f, foos)
Er, meant my first example to be:
BOOST_FOREACH(tuple

Nat Goodspeed wrote:
Eric Niebler wrote:
Why not:
int index = 0;
BOOST_FOREACH(const Foo &f, foos) { // ... stuff ... ++index; }
What value BOOST_FOREACH has comes primarily from its ability to simplify something that's already pretty darn simple -- a plain for(;;) loop. I strongly resist any effort to make BOOST_FOREACH more complicated, unless the wins are truly significant. In this case, I don't think they are.
Maybe this shouldn't be a BOOST_FOREACH feature at all. As with Python's builtin enumerate() function, maybe what we want here is an iterator adapter that dereferences to a std::pair
?
This would fit in well with the proposed resolution of https://svn.boost.org/trac/boost/ticket/3469. I'll reference this discussion from that ticket. Thanks for the suggestion. -- Eric Niebler BoostPro Computing http://www.boostpro.com

Nat Goodspeed wrote:
Maybe this shouldn't be a BOOST_FOREACH feature at all. As with Python's builtin enumerate() function, maybe what we want here is an iterator adapter that dereferences to a std::pair
?
Couldn't you just do a BOOST_FOREACH over combine(count_range(), foos) for that? (uses zip_iterator)

Eric Niebler wrote:
This is true, but I'm not convinced. What value BOOST_FOREACH has comes primarily from its ability to simplify something that's already pretty darn simple -- a plain for(;;) loop. I strongly resist any effort to make BOOST_FOREACH more complicated, unless the wins are truly significant. In this case, I don't think they are.
Thanks:) It's one of my pet peeves. How about when someone uses BOOST_FOREACH when they don't really mean foreach and intend to break out of the loop and use an internal variable outside the loop. It gets more complicated then if they'd written their own loop. BOOST_FOREACH does one thing and does it well, please leave it alone, and please don't use it when it's not what you want. If you're having to jump through hoops to make it work, it's not the right tool;) JM2C;) Patrick

2009/12/13 The Dude
It's true that none of these points is really a proof. Still, I'd be really happy to hack my own INDEX_FOREACH, but the 500+ LOCs of BOOST_FOREACH left me daunted.
It's not that hard: #define INDEX_FOREACH(index,a,b) \ for(unsigned int index = static_cast<unsigned int>(-1); \ index == static_cast<unsigned int>(-1);) \ BOOST_FOREACH(a,b) if(++index,true) INDEX_FOREACH(i, const Foo &f, foos) cout << "The bar of element " << i << " is " << f.bar() << endl;

The Dude a écrit :
However, I often need to iterate over a sequence and do some operation that depends on both the iterated element and the iteration index. E.g., I would like something like <code> BOOST_FOREACH(size_t i, const Foo &f, foos) cout << "The bar of element " << i << " is " << f.bar() << endl; </code>
Is there an easy way to do so?
The index is not something generic enough. What you would want in the general case is the iterator. But then, you might as well use the real for loop, since BOOST_FOREACH_IT couldn't be really less complicated.
participants (7)
-
Daniel James
-
Eric Niebler
-
Mathias Gaunard
-
Nat Goodspeed
-
OvermindDL1
-
Patrick Horgan
-
The Dude