与静态成员函数一起使用时关于 std::function 的问题

问题描述

为什么 PassFxn(&X::StaticmemberDoIt);PassFxn(std::bind(&X::StaticmemberDoIt,_1,_2,_3)); 都是正确的?调用 PassFxn(&X::StaticmemberDoIt); 时是否存在隐式转换,因为声明是 void PassFxn(std::function<int(float,std::string,std::string)> func) 而非 void PassFxn(int(*func)(float,std::string))

PassFxn(&X::StaticmemberDoIt);PassFxn(X::StaticmemberDoIt); 之间有什么区别?

这是演示的代码片段(https://coliru.stacked-crooked.com/a/f8a0e1bb60550958):

#include <functional>
#include <string>
#include <iostream>

void PassFxn(std::function<int(float,std::string)> func)
//           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
{
   int result = func(12,"a","b"); // call using function object
   std::cout << result << std::endl;
}

struct X
{
    int MemberDoIt(float f,std::string s1,std::string s2)
    {
        std::cout << "Member: " << f << "," << s1 << "," << s2 << std::endl;
        return 0;
    }

    static int StaticmemberDoIt(float f,std::string s2)
    {
        std::cout << "Static: " << f << "," << s2 << std::endl;
        return 0;
    }
};

int main()
{
    using namespace std::placeholders;

    X x;
    PassFxn(std::bind(&X::MemberDoIt,x,_3)); // Use a member function!

    // Or,if you have a *static* member function...
    //Why these four expression are all right?
    PassFxn(X::StaticmemberDoIt);
    
    PassFxn(&X::StaticmemberDoIt);
    
    PassFxn(std::bind(X::StaticmemberDoIt,_3));
    
    PassFxn(std::bind(&X::StaticmemberDoIt,_3)); 
    

    // ...and you can basically pass any callable object!
}

解决方法

对于常规函数(以及静态方法),从 C 继承的语法允许 f&f 作为函数指针。

函数指针和 std::bind 的结果都是可调用的,因此是 std::function 的有效参数(并作为 std::bind 的第一个参数)。