std :: function与标准函数

Pet*_*ter 0 c++ std c++17

我正在使用函数指针std :: function, 并遇到了以下问题.

让我们考虑下面的代码:

#include <cmath>
#include <functional>

// g++ -std=c++17 SF.C -o SF
// clang++ -std=c++17 SF.C -o SF

int main()
{
    typedef double (*TpFunctionPointer)(double) ;

    TpFunctionPointer pf1 = sin;                     // o.k.
    TpFunctionPointer pf2 = std::sin;                // o.k
    TpFunctionPointer pf3 = std::riemann_zeta;       // o.k

    std::function< double(double) > sf1( sin );                // o.k
    std::function< double(double) > sf2( std::sin );           // fails
    std::function< double(double) > sf3( std::riemann_zeta );  // fails
}
Run Code Online (Sandbox Code Playgroud)

用函数指针pf1,pf2,pf3和sf1 编译g++ v8.2clang v7.0工作正常.但是对于sf2和sf3,我得到一个相当长的错误消息,例如:

SF.C:17:47: error: no matching function for call to ‘std::function<double(double)>::function(<unresolved overloaded function type>)’
  std::function< double(double)> sf2( std::sin );           // fails
Run Code Online (Sandbox Code Playgroud)

这是预期的行为吗?
不应该sf2sf3没关系?

Lig*_*ica 5

多个重载<cmath> std::sin(有一个模板版本<complex>,但这不是你想要的),并且编译器不知道你想要哪一个,尽管事实上只有一个会成功绑定到你的std::function类型!在这种意义上,C++不会向后查找...

......除非它确实如此!static_cast函数指针类型有一个例外,这正是你需要的:

std::function<double(double)> sf2(static_cast<double(*)(double)>(&std::sin));
Run Code Online (Sandbox Code Playgroud)

static_castcppreference文档页面上有一个这样的例子.

对这种通用解决方案的一些潜在改进(感谢Nathan和MSalters):

std::function<double(double)> sf2(static_cast<TpFunctionPointer>(&std::sin))
Run Code Online (Sandbox Code Playgroud)

要么

std::function<double(double)> sf2([](double val){ return std::sin(val); });
Run Code Online (Sandbox Code Playgroud)