Tutorial :How do I create an elegant for_each() in C++ inside a member function where the operating function is another member function in the same class?



Question:

Here is what I'm trying to do:

//ImageCache.h:  #include <map>  #include <SDL.h>    typedef pair<const wchar_t*, SDL_Surface*> ImageNameAndSurface;  class ImageCache {  // Functions      public:          ImageCache();          ~ImageCache();          SDL_Surface* getImage(const wchar_t* imageFilename);  // Variables      private:          map<const wchar_t*, SDL_Surface*> imageFileMap;          void freeImage(const pair<const wchar_t*, SDL_Surface*>& pr); //function for_each() is to operate on  };    //ImageCache.cpp:  #include "ImageCache.h"  #include <algorithm>  #include <SDL_image.h>    ImageCache::ImageCache() {}  void ImageCache::freeImage(const pair<const wchar_t*, SDL_Surface*>& pr)  {    wcout << "Freeing " << pr.first << endl;    SDL_FreeSurface(pr.second);  }    ImageCache::~ImageCache() {      for_each(imageFileMap.begin(), imageFileMap.end(), freeImage);  }  

I'm using MSVC 2005 (compiling for Windows CE 5.0) and I get the following error:

error C3867: 'ImageCache::freeImage': function call missing argument list; use '&ImageCache::freeImage' to create a pointer to member

I understand that the function argument of for_each() expects a static function (and all of this works if I declare freeImage as static) but I'd like to know how to do this for non-static member functions. I don't understand how the implied "this" pointer is not getting passed to the call to freeImage(). Any help is greatly appreciated! I've Googled for an hour and haven't found quite this same situation for some reason.

I should add I'm trying to avoid overloading the () operator as this seems unnecessarily verbose and other similar, but obviously not compilable methods avoid this as well.


Solution:1

If you don't want to make ImageCache::freeImage a static member function, then you need to pass the this pointer. If you don't want to make a little helper class with operator () overloaded, you can use boost::bind to create the functor for you on the fly:

for_each(imageFileMap.begin(), imageFileMap.end(),           boost::bind(&ImageCache::freeImage, this, _1, _2));  


Solution:2

"for_each" is a free standing function that isn't a member of your class, so it doesn't know to pass the "this" pointer or call using member function syntax.

On that platform you'll probably need mem_fn (to make the this pointer explicit) along with bind1st (to pass the this pointer). tr1::bind (formerly boost.bind) I don't think is available to you, but if it is it's a superior solution and supersedes bind1st et al.


Solution:3

NOT

for_each(imageFileMap.begin(), imageFileMap.end(), freeImage);  

BUT

for_each(imageFileMap.begin(), imageFileMap.end(),&ImageCache::freeImage);  

for the error in question

but you will still have problems since ImageCache::freeImage is a non static (though it could be static) member function.

Making freeImage static and the change above should help.


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »