Как создать элегантный for_each () в C ++ внутри функции-члена, где рабочая функция является другой функцией-членом в том же классе? - PullRequest
2 голосов
/ 05 августа 2010

Вот что я пытаюсь сделать:

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

Я использую MSVC 2005 (компиляция для Windows CE 5.0) и получаю следующую ошибку:

ошибка C3867: 'ImageCache :: freeImage': список отсутствующих аргументов при вызове функции; используйте '& ImageCache :: freeImage' для создания указатель на член

Я понимаю, что аргумент функции for_each () ожидает статическую функцию (и все это работает, если я объявляю freeImage как static), но я хотел бы знать, как это сделать для нестатических функций-членов. Я не понимаю, как подразумеваемый указатель "this" не передается в вызов freeImage (). Любая помощь с благодарностью! Я гуглил в течение часа и по какой-то причине не нашел такой же ситуации.

Я должен добавить, что я пытаюсь избежать перегрузки оператора (), так как это кажется излишне многословным и другие подобные, но явно не компилируемые методы также избегают этого.

Ответы [ 3 ]

2 голосов
/ 05 августа 2010

Если вы не хотите делать ImageCache::freeImage статической функцией-членом, вам нужно передать указатель this. Если вы не хотите создавать небольшой вспомогательный класс с перегруженной operator (), вы можете использовать boost::bind для создания функтора для вас на лету:

for_each(imageFileMap.begin(), imageFileMap.end(),
         boost::bind(&ImageCache::freeImage, this, _1, _2));
1 голос
/ 05 августа 2010

НЕ

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

НО

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

для рассматриваемой ошибки

, но у вас все еще будут проблемы, поскольку ImageCache::freeImage не является статичным (хотяэто может быть статическая функция-член.

Помогает сделать freeImage статичным, и приведенные выше изменения должны помочь.

1 голос
/ 05 августа 2010

"for_each" - это автономная функция, которая не является членом вашего класса, поэтому она не знает, как передать указатель "this" или вызов с использованием синтаксиса функции-члена.

На этой платформе вам, вероятно, понадобится mem_fn (чтобы сделать указатель this явным) вместе с bind1st (чтобы передать указатель this). tr1 :: bind (ранее boost.bind) Я не думаю, что он доступен для вас, но если это лучшее решение, которое заменяет bind1st и др.

...