Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

Seriema

std: want to use for_each !..

This topic is 5530 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

Hi! I''m looking at my code and thinking, "what the?.. this would be so much clearer with for_each()!"
  
  ORC::ParticleFX::Container::const_iterator 
    i = particleFX.GetSystems().begin();
  for(; i != particleFX.GetSystems().end(); ++i)
    lbSystems.AddString( (*i)->GetName().c_str() );
  
but... neither mem_fun nor ptr_fun feels like the thing I need? "No lies of sugar can sweeten the sournes of reality" }+TITANIUM+{ A.K.A. DXnewbie[onMIRC]

Share this post


Link to post
Share on other sites
Advertisement
mem_fun and ptr_fun are often the wrong way to go about using algorithms such as for_each. What you really should do is write a functor. A functor is a class whose instances can behave like functions; that is, they overload the parenthesis operator. Read the STL docs for more info.


How appropriate. You fight like a cow.

Share this post


Link to post
Share on other sites
This is a rough one:


  
#include <string>

#include <vector>

#include <algorithm>

#include <functional>

using namespace std;

#include <boost\compose.hpp>

using namespace boost;



vector<Particle*> particles;
CListBox lbSystem;


for_each
(
particles.begin(),
particles.end(),
compose_f_gx(
bind1st(
mem_fun(CListBox::AddString),
&lbSystem
),
compose_f_gx(
mem_fun_ref(std::string::c_str),
mem_fun(Particle::GetName)
)
)
);


You can see why writing a functor is often easier.

Share this post


Link to post
Share on other sites

    

struct addStringToListBox {
addStringToListBox(CListBox& list)//create object that remembers the listbox

: list_(list) {}
void operator()(const Particle* particle) {// function call to add name to listbox

list_.AddString(particle->GetName().c_str());
}
private:
CListBox& list_;
};

vector<Particle*> particles;
CListBox lbSystem;

// the function object is created with the listbox as a parameter

// and gets passed to the for_each function.

// for_each calls operator()(Particle*) on the function object for every Particle* in the vector.

std::for_each(particles.begin(), particles.end(), addStringToListBox(lbSystem));


If there were other things that needed adding to the listbox other than particles you could add more: operator()(Model*), operator()(Label*) etc.

[edited by - petewood on May 28, 2003 5:02:24 AM]

Share this post


Link to post
Share on other sites
cool

I know how to make functors, I especially love my SafeDelete

I was just hoping that I didn't need to write a functor for adding strings to a list... Am I wrong to make this conclusion: making a functor for this purpose won't increase the efficiency nor the readability of my code?

Because if it doesn't, it isn't worth it

(oh for you curios people out there, having a functor SafeDelete is great! I use it everytime I want to delete a pointer, if it's "alone" or in a container!


        
struct SafeDelete
{
template <typename T>
inline void operator () ( T*& ptr ) const
{
delete ptr;
ptr = 0;
}
};


any comments on my SafeDelete? hmm come to think of it, I think I based it on one I saw in Effective STL by Scott Meyers)

"No lies of sugar can sweeten the sournes of reality"

}+TITANIUM+{ A.K.A. DXnewbie[onMIRC]

[edited by - Seriema on May 29, 2003 7:30:23 AM]

[edited by - Seriema on May 29, 2003 7:35:49 AM]

[edited by - Seriema on May 29, 2003 7:44:25 AM]

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
I have a few comments on SafeDelete... calling delete on 0 is safe, so you don''t need to check for nullity before you delete. Also, the pointer you set to 0 is a local pointer for that function, which has no effect whatsoever on the pointer you pass to SafeDelete.

Perhaps a macro instead?

Share this post


Link to post
Share on other sites
quote:
I was just hoping that I didn't need to write a functor for adding strings to a list... Am I wrong to make this conclusion: making a functor for this purpose won't increase the efficiency nor the readability of my code?


Well, you don't have to write one - I've written one for you.

I think it is far more readable than writing an explicit loop as in your first example and MKH's solution is only easy to understand if you know what's going on already! Efficiency - all three solutions will evaluate to pretty much the same thing.

Your safe delete isn't any safer by having the check for a null pointer. delete checks that anyway so you are introducing an inefficent extra check. The reason it is safe is because it remembers to set the pointer to zero afterward. Also you don't need the inline as template header functions are inline anyway.

      
struct SafeDelete
{
template <typename T>
void operator () ( T*& ptr ) const
{
delete ptr;
ptr = 0;
}
};

edit: changed to pass by reference (thanks dalleboy)

[edited by - petewood on May 29, 2003 8:48:12 AM]

Share this post


Link to post
Share on other sites
guess my edit''s didn''t come in time, unless it was you that posted torbjörn?

chatted with a friend on MSN about SafeDelete right after I posted and changed it a bit.

macros... na... they''re generally not wanted and ain''t usefull for std::algorithms

"No lies of sugar can sweeten the sournes of reality"

}+TITANIUM+{ A.K.A. DXnewbie[onMIRC]

Share this post


Link to post
Share on other sites
petewood: I was under the impression that templates only inline under the same conditions as normal inlines, no loops etc? as always, inlines are only a recommendation to the compiler. It''ll probably inline it anyway (since it''s just two rows), but I put it there more for the coder than the compiler.

I appreciated that you wrote the functor for me. If you guys think it''s more readable I''ll use it. It can be usefull for other cases later on maybe?

thinking of going up the hiearchy a little though, as high as where the function AddString() is introduced in MFC. gonna check on that..

"No lies of sugar can sweeten the sournes of reality"

}+TITANIUM+{ A.K.A. DXnewbie[onMIRC]

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

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

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!