Boost logo

Boost :

From: Eric Niebler (eric_at_[hidden])
Date: 2005-05-02 15:15:28


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

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk