【问题标题】:Question about std::function when using with static member function与静态成员函数一起使用时关于 std::function 的问题
【发布时间】:2020-12-29 01:12:29
【问题描述】:

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

PassFxn(&X::StaticMemberDoIt);PassFxn(X::StaticMemberDoIt); 有什么区别?

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

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

void PassFxn(std::function<int(float, std::string, 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 s1, std::string s2)
    {
        std::cout << "Static: " << f << ", " << s1 << ", " << s2 << std::endl;
        return 0;
    }
};

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

    X x;
    PassFxn(std::bind(&X::MemberDoIt, x, _1, _2, _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, _1, _2, _3));
    
    PassFxn(std::bind(&X::StaticMemberDoIt, _1, _2, _3)); 
    

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

【问题讨论】:

  • 对于常规函数(以及静态方法),从 C 继承的语法允许 f&amp;f 作为函数指针。
  • 函数指针和std::bind 的结果都是可调用的,因此std::function 的有效参数(以及std::bind 的第一个参数)。
  • @Jarod42 我能得出f&amp;f 相同的结论吗?
  • 对于函数,是的。
  • @Jarod42 此代码 sn-p 的 cmets(即在线 cpp.sh/9uta,引用自 cplusplus.com/reference/functional/function/function)将 f 视为函数,而将 &amp;f 视为函数指针。看来他们之间还是有一些区别的。

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


【解决方案1】:

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

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

【讨论】:

  • 由于声明是void PassFxn(std::function&lt;int(float, std::string, std::string)&gt; func) 而不是void PassFxn(int(*func)(float, std::string, std::string)),所以在调用PassFxn(&amp;X::StaticMemberDoIt); 时是否存在隐式转换?
  • 是的,你可以看看cppreference构造函数#5。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-12-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-24
  • 1970-01-01
相关资源
最近更新 更多