2010-08-05 4 views
2

Voici ce que je suis en train de faire:Comment créer un élégant for_each() en C++ dans une fonction membre où la fonction d'exploitation est une autre fonction membre de la même classe?

//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); 
} 

J'utilise MSVC 2005 (compilation pour Windows CE 5.0) et je reçois l'erreur suivante:

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

Je comprends que le L'argument function de for_each() attend une fonction statique (et tout ceci fonctionne si je déclare freeImage comme statique) mais je voudrais savoir comment le faire pour les fonctions membres non statiques. Je ne comprends pas comment le pointeur "this" implicite n'est pas passé à l'appel à freeImage(). Toute aide est grandement appréciée! Je ai googlé pendant une heure et n'ai pas trouvé tout à fait la même situation pour une raison quelconque.

Je dois ajouter que j'essaie d'éviter de surcharger l'opérateur() car cela semble inutilement prolixe et d'autres semblables, mais évidemment les méthodes non compilables l'évitent également.

+0

Assurez-vous d'ajouter des #includes afin de compiler votre exemple de code. –

+0

pensez à utiliser boost, il vous manque beaucoup, vous ne http://www.boost.org/doc/libs/1_39_0/doc/html/foreach.html. – Anycorn

+0

@aaa: même si 'BOOST_FOREACH' a ses propres limites, comme si c'était une macro ... –

Répondre

2

Si vous ne souhaitez pas faire de ImageCache::freeImage une fonction de membre statique, vous devez passer le pointeur this. Si vous ne voulez pas faire une petite classe d'aide avec operator() surcharge, vous pouvez utiliser boost::bind pour créer le foncteur pour vous à la volée:

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

n'avez-vous pas besoin de passer' * this' (c'est-à-dire une référence au lieu d'un pointeur)? Je ne suis pas expérimenté avec 'boost :: bind'. –

+0

@Matthieu, vous pouvez effectivement passer l'un ou l'autre, mais si vous passez '* this', il fera une copie de votre objet (puisque 'boost :: bind' ne passe que par valeur). Si vous voulez passer une référence, vous pouvez utiliser 'boost :: ref (* this)'. –

+0

Merci pour la précision. –

1

« for_each » est une fonction autonome qui n'est pas membre de votre classe, il ne sait donc pas passer le pointeur "this" ou appeler en utilisant la syntaxe de la fonction membre.

Sur cette plate-forme, vous aurez probablement besoin de mem_fn (pour rendre le pointeur explicite) avec bind1st (pour passer le pointeur this). tr1 :: bind (anciennement boost.bind) Je ne pense pas que vous soyez disponible, mais si c'est une solution supérieure et remplace bind1st et al.

+0

Ahhh, c'est le problème alors. Fait parfaitement sens pour moi maintenant (le problème de toute façon). En ce qui concerne la solution, je n'ai pas boost ou tr1 disponible, mais bind1st et mem_fun semblent être disponibles. Comment pourrais-je travailler ceux dans l'appel de fonction? Merci! – RotsiserMho

+0

Pour clarifier, mem_fn n'est pas disponible, mais mem_fun l'est. Est-ce que je n'ai pas de chance? Il semble que cela devrait être plus simple ... – RotsiserMho

+0

Oui, je voulais dire mem_fun (l'ancien). mem_fn est une nouvelle version nommée de manière confuse. –

1

PAS

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

MAIS

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

pour l'erreur en question

, mais vous aurez toujours des problèmes car ImageCache::freeImage est un non statique (bien qu'il puisse être statique) fonction membre . Faire freeImage statique et le changement ci-dessus devraient aider.

+0

Je peux vérifier cela fonctionne. –

+0

Ouais, ça marche. J'espérais juste un moyen d'éviter de le rendre statique puisque je prévois d'ajouter des fonctions qui utilisent les variables membres plus tard. Merci. – RotsiserMho

Questions connexes