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

Tech-Archive recommends: Repair Windows Errors & Optimize Windows Performance



In article <hevj43555ho2a29390i1hdah5dmugti9ka@xxxxxxx>, dsh@xxxxxxxx
says...
On Tue, 15 May 2007 17:29:04 +0100, Gerry Quinn <gerryq@xxxxxxxxx> wrote:

Method 1 (works for both vectors and lists):

vector< CPoint > vec;
// put some CPoints in it

vector< CPoint >::iterater it;

for ( it = vec.begin(); it != vec.end(); it++ )
{
CPoint & pt = *it;
// iterators are overloaded pointers
// they use pointer syntax
}


Method 2 (if you used a vector because you want something like an
array, only better):

vector< CPoint > vec;
// put some CPoints in it

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

Method 2 works on vectors and similar collection classes, but not on
lists, which only have iterators. But it makes for more readable code
when you're using vectors.


Get the above sorted out in your head before doing anything
complicated.

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,
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++ ];
}

2. While pointers are (random access) iterators, iterators are not
"overloaded pointers", and it is better to say that iterators are "an
abstraction of pointers". Indeed, iterators typically are not pointers at
all but class types. Even std::vector::iterator is a class type in VC7 and
later.

Fair enough. I was trying to explain the syntax to the OP in simple
terms.

I presume VC7 optimises vector::iterator down to a real pointer,
though?

3. It's arguable that the indexing approach is more readable than the
iterator approach to a loop. If I were to guess, I'd say most experienced
STL programmers use iterator loops, because that approach works across all
containers, and because STL algorithms are designed in terms of iterator
ranges, so most people end up thinking in terms of iterators by default.

I think that in the interests of readability pointers are to be avoided
where possible, and that applies equally to abstracted pointers. It
might depend on how often you use vectors etc. compared to lists,
though.

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.

5. Instead of saying std::list "only has iterators", it would be more
accurate to say that std::vector has random access iterators, while
std::list has bidirectional iterators, which is why you can use operator[]
on vectors.

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.

If it *is* altered, or more specifically if it is enlarged past its
initial capacity, the advantages of operator[] will become clear.
Though if you are doing tricks like that, vector::at may be a good
idea...

- Gerry Quinn


.



Relevant Pages

  • Re: Vector.Erase?
    ... only on iterators, not pointers. ... Don't you think setting i to zero would be a problem when the outer loop is ... gratuitously embed expressions with side-effects inside other expressions): ...
    (microsoft.public.vc.mfc)
  • Re: Bug in my code or compiler?
    ... >> as pointing before the element, it ought to make equal sense to see ... >> than your suggestion re. thinking about iterators could save. ... When you say "pointers point ...
    (alt.comp.lang.learn.c-cpp)
  • Re: arrays/vectors/templates
    ... Since you have designed your function to use iterators, ... beg and end types are not STL iterators) will cause a compile-time error ... You can make it work for pointers as well, however, using the ... std::iterator_traits template from the STL. ...
    (alt.comp.lang.learn.c-cpp)
  • Re: std::vector : begin, end and insert - Using Objects instead of ints
    ... vector< CPoint> vec; ... lists, which only have iterators. ... While pointers are iterators, ... "overloaded pointers", and it is better to say that iterators are "an ...
    (microsoft.public.vc.mfc)
  • abstract containers: does such a thing exist, conceptually?
    ... code implementing that pattern? ... behaviour by the additional pointers. ... trigger adding- or removing-operations of other iterators... ... 2)graph = list of lists: The same as above but with its own allocator ...
    (comp.object)