Изменить , чтобы учесть тот факт, что f
нельзя изменить:
Поскольку вы не можете изменить f
, единственное решение, которое я могу придумать, - это использовать какую-то глобальную переменную вместе с функцией пересылки:
int bar(int i, MyClass * mc);
namespace bar_parameters
{
MyClass * mc = 0;
}
int binded_bar(int i)
{
return bar(i, bar_parameters::mc);
}
int main()
{
MyClass myclass(input);
bar_parameters::mc = &myclass;
double retval = f(binded_bar);
}
Это довольно некрасиво, однако ...
Невозможно связать параметры функции. Однако это возможно с помощью функтора (объекта функции).
Первое, что вам нужно сделать, это изменить параметр f
, чтобы он стал функциональным объектом, таким как std::function
или boost::function
, вместо указателя функции:
double f(std::function<int (int)> foo);
Вы можете использовать эту функцию либо с указателями на функции, либо с функторами с правильной сигнатурой.
После этого вы можете использовать методы привязки, такие как std/boost::bind
(или bind1st
/ bind2nd
в C ++ 03):
double retval = f(std::bind(bar, _1, &myclass));
Если у вас нет доступа к Boost или C ++ 0x, вы можете использовать обычную технику, заключающуюся в создании шаблона параметра для принятия любых вызываемых объектов (указателей на функции и функторов):
template <typename Func>
double f(Func foo);
Недостаток этого подхода заключается в том, что подпись функции применяется только при использовании ее в f
.
Чтобы связать второй параметр, вы можете затем использовать ptr_fun
для преобразования указателя функции в объект функции и bind2nd
для фактического связывания параметра:
double retval = f(std::bind2nd(std::ptr_fun(bar), &myclass));