Как объяснил Xeo, можно заставить его работать, даже если функция перегружена с использованием явного приведения.Однако, поскольку вы уже используете std :: function (которая является функцией C ++ 11), вы также можете просто использовать лямбда-выражение в качестве инициализатора:
function<double(double)> fLog = [](double x){return std::log(x);};
Это предпочтительно в C ++11, потому что это позволяет избежать проблем с перегрузкой.Кроме того, это более эффективно, чем перенос указателя функции, поскольку он сохраняет один уровень косвенности и, следовательно, позволяет встроить лямбда-тело в оператор вызова функции внутреннего объекта-оболочки.
Следует, вероятно, подчеркнуть, что использованиеstd :: function в вашем примере не нужна, поскольку Eval уже является шаблоном функции, а параметр типа FOper может точно соответствовать типу объекта функции без необходимости заключать его в std :: function.Так что, если вам не нужно стирание типа, полученное с помощью std :: function, вы можете написать
template <typename FOper>
double Eval(FOper fOper, double X)
{
return fOper(X);
}
int main()
{
auto flog = [](double x){return std::log(x);};
std::cout << Eval(flog, 10.0) << std::endl;
}