
Stefan Strasser wrote:
Eric Niebler schrieb:
Even when writing loops by hand, it's a good idea to save the result of .end() in a local to avoid repeated function calls that are not necessary. It's called "hoisting". It's one of the side-benefits of using FOREACH and std:: algorithms.
I think it's not worth it here. besides that it isn't a performance overhead on most containers you don't expect that from a keyword.
Huh, *I* would expect that from a keyword.
and it is not consistent:
char str[]={'a','b',0,0}; foreach(char c,str){ str[2]='c'; std::cerr << c << std::endl; }
output is "abc".
Right. When iterating a null-terminated string, there isn't any need to find the end of the sequence up front. I just quit at the first null-terminator.
std::string str="ab"; foreach(char c,str){ if(str.length() == 2) str+='c'; std::cerr << c << std::endl; }
output is "ab".
See the discussion about iterator invalidation. This code has undefined behavior. You have found an interesting inconsistency, though. In the case of null-terminated strings, I felt I could be smarter than Boost.Range (which uses std::strlen() to find the end). You can only detect the difference in this one scenario, though, and I consider the perf win to be worth it. But I don't have strong feelings on the issue. -- Eric Niebler Boost Consulting www.boost-consulting.com