错误传递std :: function vs函数指针作为参数

时间:2014-05-26 22:53:13

标签: c++ c++11 function-pointers std-function

我有以下代码,其中我声明了2个函数,它们将函数作为参数(一个使用std::function,另一个使用指向函数的指针)。作为参数的函数必须具有原型std::complex<double>(const std::complex<double>&)。这种参数的一个例子是C ++ 11中的std::sqrt,参见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 个答案:

答案 0 :(得分:2)

std::sqrt有多个重载,您的代码不知道如何确定您想要的那个。

尝试:

typedef cplx(*complex_function)(const cplx &);

std::cout << f_of_ten( complex_function( std::sqrt ) ) << std::endl;

答案 1 :(得分:1)

不好主意,看评论和编辑!

复数的std::sqrt是一个模板,如果您使用std::sqrt<double>您的代码可以使用。

不确定为什么g ...变种适用于你。

编辑以挽救此答案:

您可以使用lambda来选择正确的sqrt

std::cout << f_of_ten([](cplx x){return std::sqrt(x);}) << std::endl;

现在将进行模板参数推导和重载解析,选择正确的sqrt并将其打包在绑定到std::function的lambda中。