The Artima Developer Community
Sponsored Link

The C++ Source
Conditional Love: FOREACH Redux
by Eric Niebler
February 17, 2005

<<  Page 4 of 4



You may not have thought much about the conditional operator before now, but you have to admit, there is a lot there to love. The standard devotes a whole page and a half of dense standardese to this curious little beast, and we have just scratched the surface. But I think you'll forgive me if I take my language lawyer hat off now. I encourage you to download the code for BOOST_FOREACH. There you will find a version that works with other types of sequences besides STL containers. BOOST_FOREACH is currently under consideration for inclusion in Boost. You can find the code in the Boost Sandbox File Vault in the file


Thanks go out to Andrei Alexandrescu, Chuck Allison, and especially Scott Meyers for their detailed and thoughtful reviews of this article. I am also deeply indebted to Thorsten Ottosen for his Boost.Range library [8], which made it trivial to extend BOOST_FOREACH to work with other collection types besides STL containers. Finally, I would like to thank Anson Tsao for his initial insight which led to BOOST_FOREACH in the first place.

Notes and References

  1. ScopeGuard by Andrei Alexandrescu.
  2. If you look at Listing 1, you'll notice that the variables are declared in "if" statements. Text substitution can be a dangerous thing. The if/else statements serve to make FOREACH expand to one big statement, which makes it play nicely with any surrounding code. I leave the if/else statements out here because it would only obscure the point.
  3. The terms originally come from the fact that lvalues can appear on the left side of an assignment, and rvalues can only appear on the right.
  4. boost::variant is a discriminated union.
  5. It's not difficult to get the answer right in most cases, but getting it right in all cases is a challenge. A common trick uses the rules for binding to references. Ordinarily, rvalues will not bind to references, and this can be detected. Unfortunately, const-qualified rvalues will bind to references, so the technique is not perfect.
  6. In fact, on many compilers it doesn't work, sadly. It works on Comeau and on gcc 3.3.3, but not on Visual C++ 7.1, from my experiments.
  7. The reason is because operator L & () const is const- qualified and operator R () is not. Since the expression rvalue_probe() is not const, in order to call a const- qualified member function, the compiler must add a const qualification to the rvalue_probe object. This is considered a conversion. As a result, the conversion sequence using operator R() is shorter than the sequence using operator L &() const, and hence it is preferred.
  8. Boost.Range by Thorsten Ottosen.

About the Author

Eric Niebler is an independent C++ consultant currently working with Dave Abrahams and Boost Consulting. Formerly of Microsoft Research, Eric has also written template libraries for Visual C++. He is the author of the GRETA Regular Expression Template Library. When not writing C++ for a living, he can often be found in coffee shops around Seattle writing C++ for fun.

<<  Page 4 of 4

Sponsored Links

Copyright © 1996-2018 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use