C++ 使用std::function对非指针对象调用成员函数

C++ 使用std::function对非指针对象调用成员函数,c++,std-function,this-pointer,C++,Std Function,This Pointer,代码如下所示 std::string::empty()应将this指针作为类型为指针的参数,std::string* 在2和3行的呼叫怎么可能正常 #include <iostream> #include <functional> int main() { std::string str{"A small pond"}; std::function<bool(std::string*)> fp = &std::string::emp

代码如下所示

std::string::empty()
应将
this
指针作为类型为指针的参数,
std::string*

2
3
行的呼叫怎么可能正常

#include <iostream>
#include <functional>

int main() {
    std::string str{"A small pond"};

    std::function<bool(std::string*)> fp = &std::string::empty;
    std::cout << fp(&str) << std::endl; // 1

    std::function<bool(std::string)> f = &std::string::empty;
    std::cout << f(str) << std::endl; // 2

    std::function<bool(std::string&)> fr = &std::string::empty;
    std::cout << fr(str) << std::endl; // 3
}

/*
output:
0
0
0
*/

std::function
可以接受与其类型签名匹配的任何可调用项。调用时,使用以下规则(引号)计算可调用参数和参数:

  • 如果
    f
    是指向类
    T
    的成员函数的指针:
    • 如果
      std::is_base_of::value
      true
      ,则
      调用(f,t1,t2,…,tN)
      相当于
      (t1.*f)(t2,…,tN)
    • 如果
      std::decay\u t
      std::reference\u wrapper
      的专门化,那么
      调用(f,t1,t2,…,tN)
      是 相当于
      (t1.get()*f)(t2,…,tN)
    • 如果
      t1
      不满足前面的项目,那么
      调用(f,t1,t2,…,tN)
      相当于
      (*t1)。*f)(t2,…,tN)

因此,第一种情况的计算方法类似于
(*t1)。*f()
,另外两种情况的计算方法类似于
t1.*f()

std::function
可以接受与其类型签名匹配的任何可调用函数。调用时,使用以下规则(引号)计算可调用参数和参数:

  • 如果
    f
    是指向类
    T
    的成员函数的指针:
    • 如果
      std::is_base_of::value
      true
      ,则
      调用(f,t1,t2,…,tN)
      相当于
      (t1.*f)(t2,…,tN)
    • 如果
      std::decay\u t
      std::reference\u wrapper
      的专门化,那么
      调用(f,t1,t2,…,tN)
      是 相当于
      (t1.get()*f)(t2,…,tN)
    • 如果
      t1
      不满足前面的项目,那么
      调用(f,t1,t2,…,tN)
      相当于
      (*t1)。*f)(t2,…,tN)

因此,第一个案例的评估方式是
(*t1)。*f()
,另外两个案例的评估方式是
t1.*f()

@DavidSchwartz我修改了标题。
str.empty()
是合法的。将调用包装在
std::function
中也可以。@PeteBecker如何从语法或类型转换的角度解释它?@DavidSchwartz我修改了标题。
str.empty()
是合法的。将调用包装在
std::function
中也可以。@PeteBecker如何从语法或类型转换的角度解释它?
clang version 9.0.0-2~ubuntu18.04.2 (tags/RELEASE_900/final)
g++ (Ubuntu 8.4.0-1ubuntu1~18.04) 8.4.0