Указатель функции-члена C++

Рассмотрим следующий класс

class Foo
{
    typedef bool (*filter_function)(Tree* node, std::list<std::string>& arg);

    void filter(int filter, std::list<std::string>& args)
    {
        ...
        if (filter & FILTER_BY_EVENTS) {
            do_filter(events_filter, args, false, filter & FILTER_NEGATION);
        }
        ...
    }

    void do_filter(filter_function ff, std::list<std::string>& arg, 
        bool mark = false, bool negation = false, Tree* root = NULL)
    {
        ...
    }

    bool events_filter(Tree* node, std::list<std::string>& arg)
    {
        ...
    }
};

Я могу передать events_filter в качестве параметра do_filter только тогда, когда events_filter является static членом. Но я не хочу делать это static. Есть ли способ передать указатель на функцию-член другой функции? Возможно, используются библиотеки ускорения (например, функция) или что-то в этом роде.

Спасибо.


person maverik    schedule 31.03.2011    source источник


Ответы (1)


bool (Foo::*filter_Function)(Tree* node, std::list<std::string>& arg)
Дает вам указатель на функцию-член. Вы передаете один с:

Foo f;
f.filter(&Foo::events_filter,...);

И вызовите его с помощью:

(this->*ff)(...); // the parenthesis around this->*ff are important

Если вы хотите иметь возможность передавать любую функцию/функтор, которая соответствует вашему синтаксису, используйте Boost.Function или, если ваш компилятор поддерживает это, используйте std::function.

class Foo{
  typedef boost::function<bool(Tree*,std::list<std::string>&)> filter_function;

  // rest as is
};

А потом передать все, что вы хотите. Функтор, свободная функция (или статическая функция-член) или даже нестатическая функция-член с Boost.Bind или std::bind (опять же, если ваш компилятор это поддерживает):

Foo f;
f.do_filter(boost::bind(&Foo::events_filter,&f,_1,_2),...);
person Xeo    schedule 31.03.2011
comment
Подробное объяснение указателей на функции-члены см. в C++ FAQ Lite: parashift.com/c++-faq-lite/pointers-to-members.html - person Julien-L; 31.03.2011
comment
Просто исправьте орфографию filer -> filter. - person Serge Dundich; 31.03.2011