Ошибка передачи std::function против указателя на функцию в качестве параметра
У меня есть следующий кусок кода, в котором я объявляю 2 функции, которые принимают функцию в качестве параметра (одна с помощью std::function
другой с помощью указателя на функцию). Функция, взятая в качестве параметра, должна иметь прототип std::complex<double>(const std::complex<double>&
). Примером такого параметра является std::sqrt
в C++11 см. http://en.cppreference.com/w/cpp/numeric/complex/sqrt. Теперь я абсолютно не понимаю, почему работает функция, которая принимает указатель на функцию (т.е. g_of_ten
), тогда как другой, который занимает std::function
как параметр, не (т.е. f_of_ten
). Если я раскомментирую строку
//cout << f_of_ten(std::sqrt) << endl; // ERROR here!!!
Я получаю ошибку
error: no matching function for call to 'f_of_ten'
cout << f_of_ten(std::sqrt) << endl; // ERROR here!!!
^~~~~~~~
/Users/vlad/minimal.cpp:10:6: note: candidate function not viable: no overload of 'sqrt' matching 'std::function<cplx (const cplx &)> &' for 1st argument
cplx f_of_ten(std::function<cplx(const cplx &)>& x)
^
1 error generated.
Я полностью озадачен, почему это происходит, хотя я std::function
действительно обертка для всех видов функторов (включая стандартные функции). Любая помощь приветствуется! Ниже приведен код:
#include <cmath>
#include <complex>
#include <functional>
#include <iostream>
using namespace std;
using cplx = complex<double>; // to save some typing
cplx f_of_ten(std::function<cplx(const cplx &)> x) // the problematic one
{
return x(10);
}
cplx g_of_ten(cplx(*x)(const cplx &)) // this works
{
return (*x)(10);
}
int main()
{
//cout << f_of_ten(std::sqrt) << endl; // compile ERROR here!!!
cout << g_of_ten(std::sqrt) << endl;
}
PS: я, конечно, тоже пробовал cout << f_of_ten(&std::sqrt) << endl;
та же история, ошибка времени компиляции.
@Yakk,
это работает нормально:
#include <cmath>
#include <complex>
#include <functional>
#include <iostream>
#include <valarray>
using cplx = std::complex<double>; // to save some typing
cplx f_of_ten(std::function<cplx(const cplx &)> x) // the problematic one
{
return x(10);
}
cplx g_of_ten(cplx(*x)(const cplx &)) // this works
{
return (*x)(10);
}
int main()
{
//cout << f_of_ten(std::sqrt<double>) << endl; // compile ERROR here!!!
std::cout << g_of_ten(std::sqrt) << std::endl;
}
2 ответа
Плохая идея, смотрите комментарии и редактируйте!
std::sqrt
для комплексных чисел это шаблон, если вы используете std::sqrt<double>
ваш код работает.
Не уверен, почему твой вариант работает.
Изменить, чтобы спасти этот ответ:
Вы можете использовать лямбду, чтобы выбрать правильный sqrt
лайк
std::cout << f_of_ten([](cplx x){return std::sqrt(x);}) << std::endl;
Теперь произойдет удержание аргумента шаблона и разрешение перегрузки, выберите правильный sqrt
и упаковать его в лямбду, которая связывает с std::function
,
Существует более одной перегрузки std::sqrt
и ваш код не знает, как определить, какой вы хотите.
Пытаться:
typedef cplx(*complex_function)(const cplx &);
std::cout << f_of_ten( complex_function( std::sqrt ) ) << std::endl;