Vector access: iterators?

Started by
7 comments, last by MaulingMonkey 18 years, 7 months ago
Say I have a std::vector of Entity's. I want to invoke the doUpdate-method on all of them. I would then write:

for( size_t i = 0; i < m_entities.size(); i++ )
   m_entities.doUpdate();
However, I often see iterators used, which would give:

for( std::vector<Entity>::iterator i = m_entities.begin(); 
                                   i != m_entities.end(); ++i )
   (*i).doUpdate();
The question: I find the first solution more readable and easier to type. However, what are the reasons to use the second method? Coherency with lists (where you can't use []), speed, l33tness??
Advertisement
It's up to you, but if you want to create a templated function that accepts any kind of list, you'll have to use the iterator method, because only the vector accepts the [] operator, as you already pointed out.

You use the [] operator in cases where you used a vector because you needed random access.
Quote:Original post by DaBono
The question: I find the first solution more readable and easier to type. However, what are the reasons to use the second method? Coherency with lists (where you can't use []), speed, l33tness??


The second solution is a good habit because you can iterate an abstract structure; so if you change the data structure (for example a list or a map) you have not to change your existing code.
In this case is also a good practice the use of typedef.

typedef std::vector<Entity> ENTITIES;// or typedef std::list<Entity> ENTITIES;...//later, or in other modules, you will use the same code...for( ENTITIES::iterator i = ...)
Also, supposing it is a string iterator then the string.insert() is best used by passing an interator for the insertion point.

ace
std::for_each(m_entities.begin(),m_entities.end(),uglyadapter(&Entity::doUpdate))

is what you are looking for (with a suitable uglyadapter thingy).

Especially for the l33tness part ;)
Quote:Original post by Trap
std::for_each(m_entities.begin(),m_entities.end(),uglyadapter(&Entity::doUpdate))

is what you are looking for (with a suitable uglyadapter thingy).

Especially for the l33tness part ;)


The boost::lambda libraries can provide a suitable uglyadapter thingy:

#include<boost/lambda/lambda.hpp>#include <boost/lambda/bind.hpp>using namespace std;using namespace boost::lambda;...for_each((m_entities.begin(),m_entities.end(), bind(&Entity::doUpdate, _1));
 ~~C--O   -
Why use Boost.Lambda for that?

#include <algorithm>#include <functional>using namespace std;for_each(m_entities.begin(), m_entities.end(), mem_fun_ref(&Entity::doUpdate));

Should work, but I don't have a compiler handy to check.
Quote:Original post by jdhardy
Why use Boost.Lambda for that?

#include <algorithm>#include <functional>using namespace std;for_each(m_entities.begin(), m_entities.end(), mem_fun_ref(&Entity::doUpdate));

Should work, but I don't have a compiler handy to check.


I tested it, and it does work. The only advantage I can see to the boost::lambda is the same code would work with a vector of Entity*, but that's not what he has, so may as well stick with the standard library.
 ~~C--O   -
Quote:Original post by Couvillion
I tested it, and it does work. The only advantage I can see to the boost::lambda is the same code would work with a vector of Entity*, but that's not what he has, so may as well stick with the standard library.


That's a simple matter of replacing mem_fun_ref with mem_fun during that situation, or boost::mem_fn (not a typeo) if you truely want them both. Bind is a bit much for something so simple :-).

Quote:I find the first solution more readable and easier to type.


That's because it is. The advantages of the second would be interoperability with any container type (the core concept of iterators). It's what lets std::for_each work with so many containers. The key here is it allows for more reuse. Although an ugly heart may have std::for_each, it glistens on the outside, beautiful, like raindrop. Code reuse taken to the extreme. They're reusing the humble for loop for hecks sake!

My continued use of std::for_each indicates I do not consider this a bad thing.

This topic is closed to new replies.

Advertisement