Передавать указатели на функции-члены или не-члены в качестве параметров
У меня есть структура с именем 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, но поддерживал бы функции, не являющиеся членами и членами?
3 ответа
Пост 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;
}
Принимать 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));
С 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));