Jump to content
  • Advertisement
Sign in to follow this  
DaBono

Vector access: iterators?

This topic is 4648 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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??

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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 = ...)

Share this post


Link to post
Share on other sites
Also, supposing it is a string iterator then the string.insert() is best used by passing an interator for the insertion point.

ace

Share this post


Link to post
Share on other sites
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 ;)

Share this post


Link to post
Share on other sites
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));

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!