Re: std::vector : begin, end and insert - Using Objects instead of ints



In article <u5bu43dep04mnh4mv3ugma7gv6cltgl7t9@xxxxxxx>, dsh@xxxxxxxx
says...
On Fri, 18 May 2007 16:52:24 +0100, Gerry Quinn <gerryq@xxxxxxxxx> wrote:
In article <hevj43555ho2a29390i1hdah5dmugti9ka@xxxxxxx>, dsh@xxxxxxxx
says...

Some things to note:

1. When there's a choice, prefer preincrement to postincrement, because pre
doesn't require creation of a temporary object to return the original
value. That is, use ++it instead of it++. (I know, K&R taught the opposite,
but this is C++, which itself would have been better named ++C. <g>)

My view is that readability trumps efficiency in most cases,

The thing is, efficiency can be measured objectively, while "readability"
is highly subjective. I'm not interested in arguing which is more
"readable", ++i or i++. However, besides being more efficient for most
class types, ++i is definitely easier to think about than i++, because the
former simply increments i, while the latter creates a temporary copy of i,
increments i, and returns the temporary, which is ultimately discarded
without being used in the case we're discussing. While it makes most of the
same points, you might want to read what the C++ FAQ says about this:

http://www.parashift.com/c++-faq-lite/operator-overloading.html#faq-13.15

The bottom line is that in C++, it's conventional to use pre when there's a
choice, and there are decent reasons for this.

Sure, but I happen to think readability is a decent reason to choose
the opposite,

particularly where the efficiency gain is likely to be very small or
nonexistent. I find postincrement more readable, and use it everywhere
except for special cases. Postincrement certainly seems more idiomatic
in for loops, because if you are incrementing in the body of the loop
you will need to use it:

for ( int i = 0; i < vec.size(); )
{
CPoint & pt = vec[ i++ ];
}

FWIW, many people would say that embedding expressions with side-effects
inside other expressions is not very "readable". Again, this is a departure
from K&R thinking, and I don't necessarily agree with it, at least not in
all cases, because there are times when it would actually be incorrect to
split the operation into two statements, e.g. when erasing a list iterator.

It's certainly a common enough idiom, especially when incrementing
pointers.

In any event, I think you're really reaching to motivate something you
probably learned very early on. I wonder, what do you do for reverse
iteration? Do you really sit down and think about how you might write a
certain kind of loop that omits stmt3 in a for-loop header when you decide
how to write stmt3 for the vast majority of loops, when the former is
driven by correctness considerations and the latter is not?

I don't think I'm reaching. Reverse iteration is a relatively unusual
procedure, and again readability is probably the main reason, as often
there is no computational reason why one should iterate forwards or
backwards. Forward is more natural - just like postincrement ;-)

If statement 3 can be in the same format as a statement in the body
that would do the same thing, that seems an advantage. Maybe it
doesn't seem a large advantage to you, but it is there.

(BTW, vector::size returns vector::size_type, which is an unsigned type.
Consequently, you really shouldn't use int for your index type.)

True, but unlikely to be of consequence in this age. Again, I feel int
is more readable.

4. The vector::at function is not really an "alternative" to operator[],
because the former checks its argument and throws an exception if it's out
of bounds. The latter doesn't perform any error-checking, and thus there
are major differences in performance and behavior between the two.

Then it's *exactly* an alternative! If it were the same it would
effectively be an alias.

The problem is, lots of people will read an unqualified "alternative" claim
as an "equivalence" claim. I think that's perfectly understandable
considering how you presented it:

CPoint & pt = vec[ i ];
// or alternatively
CPoint & samething = vec.at( i );

That's fair enough. But consider the context: the OP was completely
baffled at how to use these things in the first place! Presumably he
will at some point press F1 for the details. (I would not have
mentioned vector::at at all had he not - but you're right, I should
have pointed out the difference, even if they return the same result.)

6. If you're really nuts about efficiency, don't use vec.end() (or
vec.size()) in your loop condition. Instead save its value to a (const)
variable and use it instead.

I'd rather hope that the optimiser would take care of that, so long as
the size of the vector is not altered inside the loop.

Here's a little program fragment for you to try:

[--]

Compiled with:

cl -c -FAs -O2 -EHsc -W4 a.cpp

VC2005 optimizes the end() call but not size(), and the dereferencing of
the iterator is more efficient as well.

Hmmm... I've never been a great believer in the alleged superiority of
compilers to mere humanity which is often expressed these days, but
even I thought it would handle that!

- Gerry Quinn


.



Relevant Pages

  • Re: std::vector : begin, end and insert - Using Objects instead of ints
    ... When there's a choice, prefer preincrement to postincrement, because pre ... The thing is, efficiency can be measured objectively, while "readability" ... split the operation into two statements, e.g. when erasing a list iterator. ... certain kind of loop that omits stmt3 in a for-loop header when you decide ...
    (microsoft.public.vc.mfc)
  • Re: C# Command to Wait a Specified Period of Time
    ... But the key to use the query syntax is you don't do the for each loop yourself, instead you state what you want, not how to do it. ... I'm sure that once one gains experience with these newer language constructs that they do enhance "readability" - for the people who know and use them. ... But don't go around saying that a code block consisting of delegates and anonymous methods is "more readable" than a simple "for loop". ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: wich is faster
    ... On the premature optimisation front - it has to be a judgement call by ... an "& 1" and a simple loop dividing n by odd numbers from 3 to sqrt. ... I do not accept that readability is an excuse ...
    (comp.programming)
  • Re: newbie: need inspiration
    ... Value holding input isn't really ... Loop should end when user ... > something with the login and password after the loop): ... which is very bad for readability. ...
    (comp.unix.shell)