std: want to use for_each !..

Started by
25 comments, last by Seriema 20 years, 10 months ago
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]
[ ThumbView: Adds thumbnail support for DDS, PCX, TGA and 16 other imagetypes for Windows XP Explorer. ] [ Chocolate peanuts: Brazilian recipe for home made chocolate covered peanuts. Pure coding pleasure. ]
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.
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.
- The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara

    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]
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]
[ ThumbView: Adds thumbnail support for DDS, PCX, TGA and 16 other imagetypes for Windows XP Explorer. ] [ Chocolate peanuts: Brazilian recipe for home made chocolate covered peanuts. Pure coding pleasure. ]
http://boost.org/libs/lambda/doc/index.html
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?
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]
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]
[ ThumbView: Adds thumbnail support for DDS, PCX, TGA and 16 other imagetypes for Windows XP Explorer. ] [ Chocolate peanuts: Brazilian recipe for home made chocolate covered peanuts. Pure coding pleasure. ]
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]
[ ThumbView: Adds thumbnail support for DDS, PCX, TGA and 16 other imagetypes for Windows XP Explorer. ] [ Chocolate peanuts: Brazilian recipe for home made chocolate covered peanuts. Pure coding pleasure. ]

This topic is closed to new replies.

Advertisement