Ошибка передачи 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;
Другие вопросы по тегам