首页 > 解决方案 > 使用 std::function 对非指针对象调用的成员函数

问题描述

代码如下。

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
*/
clang version 9.0.0-2~ubuntu18.04.2 (tags/RELEASE_900/final)
g++ (Ubuntu 8.4.0-1ubuntu1~18.04) 8.4.0

标签: c++std-functionthis-pointer

解决方案


std::function可以接受任何与其类型签名匹配的Callable 。调用时,可调用和参数使用以下规则进行评估(引用cppreference):

  • Iff是指向类的成员函数的指针T
    • 如果std::is_base_of<T, std::decay_t<decltype(t1)>>::valuetrue,则INVOKE(f, t1, t2, ..., tN)等价于 (t1.*f)(t2, ..., tN)
    • 如果std::decay_t<decltype(t1)>是 的特化std::reference_wrapper,则INVOKE(f, t1, t2, ..., tN)等价于(t1.get().*f)(t2, ..., tN)
    • 如果t1不满足前面的项目,则INVOKE(f, t1, t2, ..., tN)等价于((*t1).*f)(t2, ..., tN)

因此,第一种情况的评估方式为 like (*t1).*f(),其他两种情况的评估方式为t1.*f().


推荐阅读