
Vladimir Prus wrote:
Eric, I've some questions about BOOST_FOREACH (which is pretty cool, BTW).
Thanks!
1. Is it possible to use typeof on gcc, to avoid any possible overhead? While you've posted some results which show that gcc generally can optimise it very well, I'd like to be 100% sure). Something like:
#define FOR_EACH(var, container) \ for(typeof(container.begin()) _for_each_i = container.begin(),\ _for_each_e = container.end();\ _for_each_i != _for_each_e; ++_for_each_i)\ if(bool _for_each_continue = false) {}\ else\ for(var = *_for_each_i; !_for_each_continue; _for_each_continue=true)
which works perfectly for me.
It's probably possible, but there are a couple of subtle issues that would need to be dealt with. First, BOOST_FOREACH should be extensible, meaning, there should be a well-defined way to "hook" BOOST_FOREACH to get it to enumerate other user-defined collections. The mechanism to hook BOOST_FOREACH should be the same regardless of whether BOOST_FOREACH is implemented with native typeof or not. Second, BOOST_FOREACH should work out of the box with arrays, null-terminated strings and iterator pairs in addition to STL(-like) containers. The second should be easy, but the first would require some careful design. Considering that BOOST_FOREACH is pretty optimal already, I'm not convinced it's worth it. Also, note that the above version is buggy because it doesn't handle break statements correctly.
2. Any chance that
BOOST_FOREACH((pair<int, int> p), container)
will work? I don't know how to make it work without require paranthethis in all cases, but maybe there's a smart trick.
I don't think so, sorry. You would have to use a typedef, as in: typedef pair<int,int> pair_int; BOOST_FOREACH( pair_int p, container )
3. Is it possible that you place this to sandbox, for easier access?
Done. It's at boost-sandbox/boost/foreach.hpp. You'll notice that it's a reimplementation. This version only evaluates the container expression once, so you can use complicated expressions as the second parameter. This makes BOOST_FOREACH very useful with filtered ranges, where the element type is simple, but the type of the "container" is very complicated. I'll probably need some docs and tests at some point. It's really quite useful and safe now(*) so perhaps I'll actually put it up for review soon. (*) There is one outstanding problem that I have not yet solved. I think it's unsolvable in the current language, but I hope I'm wrong. The current implementation does the wrong thing when the container expression is a const-qualified rvalue STL container. It uses the rules for binding to reference to distinguish lvalues from rvalues, storing references for lvalues and copies for rvalues. Const-qualified rvalues screw this up, so the following crashes: std::vector<int> const get_vector(); ... BOOST_FOREACH( int i, get_vector() ) I'm not sure how serious this problem is. If anyone knows of a foolproof way to distinguish lvalues from rvalues, I'm all ears. -- Eric Niebler Boost Consulting www.boost-consulting.com