Передавать указатели на функции-члены или не-члены в качестве параметров

У меня есть структура с именем Foo, которая содержит функцию, которая вызывает любой метод, который он передал и возвращает значение.

struct Foo
{
unsigned char fooFunc(unsigned char param, unsigned char(getValueMethod)(const unsigned char))
{
return getValueMethod(param);
}
};

У меня есть метод с именем barFunc …

static unsigned char barFunc(const unsigned char paramA)
{
return paramA * 2;
}

…которые можно красиво передать в fooFunc

Foo foo1;
foo1.fooFunc(10, &barFunc);

Но я также хочу, чтобы fooFunc принимала функции-члены, такие как bazFunc ….

struct Baz
{
unsigned char bazFunc(const unsigned char paramB)
{
return paramB * 3;
}
};

…так называться …

Foo foo2;
Baz baz;
foo2.fooFunc(10, ?????);

…но это не верно.

Все, что я нашел в отношении передачи функций-членов в качестве параметров, говорит о том, что нужно знать, из какого класса происходит объект, до того, как он будет вызван, а это значит, что мне придется создать 2 функции вместо одной.

Есть ли способ, который я еще не нашел, который потребовал бы только 1 метод fooFunc, но поддерживал бы функции, не являющиеся членами и членами?

2

Решение

пост c ++ 11, как и на другие ответы

до c ++ 11:

#include <iostream>
#include <functional>using namespace std;

struct foo_holder {

template<class T>
unsigned char foo(unsigned char v, T f) {
return f(v);
}

};

unsigned char bar(unsigned char param) {
return param * 2;
}

struct baz {
unsigned char bar(unsigned char param) {
return param * 3;
}
};

int main()
{
cout << "Hello World" << endl;

foo_holder f;
baz b;

cout << static_cast<int>(
f.foo(6, bar)
) << endl;

cout << static_cast<int>(
f.foo(6, std::bind1st(std::mem_fun(&baz::bar), &b))
) << endl;

return 0;
}
1

Другие решения

принимать boost::function<signature> передать результат boost::bind()

bool free_func(std::string const& arg) { ... }

struct X {
bool mem_func(std::string const& arg) { ... }
};

...
typedef boost::function<bool (std::string const& name)> func_t;

std::vector<func_t> funcs;
X x;

funcs.push_back(boost::bind(&X::mem_func, x, _1));
funcs.push_back(boost::bind(&free_func, _1));
3

С C ++ 11 или boost ваша задача проста — но поскольку вы хотите иметь решение C ++ 03, то, как предлагается в комментариях, используйте функцию-член шаблона:

struct Foo
{
template <typename Function>
unsigned char fooFunc(unsigned char param, Function getValueMethod)
{
return getValueMethod(param);
}
};

Тогда с примером бесплатной функции вы не будете ничего менять:

Foo foo1;
foo1.fooFunc(10, &barFunc);

С функцией-членом — просто используйте C ++ 03 std::mem_fun/bind1st из C ++ 03 <functional>:

#include <functional>
Foo foo2;
Baz baz;
foo2.fooFunc(10, std::bind1st(std::mem_fun(&Baz::bazFunc), &baz));
1
По вопросам рекламы [email protected]