c++ - std::function 如何使指向成员函数的指针起作用?

标签 c++

更新:以某种方式与how-is-stdfunction-implemented相关

该程序将不同的函数指针(来自结构的乘法、作为函数的除法和作为 lambda 的加法)插入 vector ,然后使用相同的参数调用元素。问题仅来自结构。

它与 std::function 一起工作得很好,但在使用函数指针时我无法编译它。有谁知道如何修复程序吗?或者更好的是,std::function 是如何工作的?如果我改用静态成员函数,程序就会变得微不足道(下面不包括)。

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

struct mult {
    double operator()(double a, double b) { return a * b; }
    double fun(double a, double b) { return a * b; }
};

double add(double a, double b) {
    return a + b;
}

using namespace std;

int main(){

    using fnc = function<double(double, double)>;
    vector<fnc> functions;
    functions.push_back(mult{});
    functions.push_back([](double a, double b) {return a / b; });
    functions.push_back(add);

    double a = 3, b = 4;
    cout << "a=" << a << ", b=" << b << endl;
    for (int i = 0; i < 3; ++i)
        cout << functions[i](a, b) << endl;
    cout << endl;

    typedef double (*fp)(double, double);
    fp funPtr;
    vector<fp> functions1;

    //functions1.push_back(mult{}); error

    typedef double (mult::*mfp)(double, double);
    mfp f = &mult::fun;
    mult * obj = new mult;
    cout << (obj->*f)(3, 4) << endl;//          OK!
    //functions1.push_back(mfp);        ERROR!
    //functions1.push_back(obj->*f);    ERROR!
    //functions1.push_back(&mult::fun); ERROR!

    functions1.push_back([](double a, double b) {return a / b; });
    functions1.push_back(add);
    for (int i = 0; i < 2; ++i)
        cout << functions1[i](a, b) << endl;

    std::cout << "\npres enter to exit...";
    int wait_key = getchar();
    return 0;
}

最佳答案

成员函数有一个隐藏的第一个参数,它是指向调用它的对象的指针。所以

double mult::operator()(double a, double b) { return a * b; }

实际上(有点)等于

double operator()(mult* this, double a, double b) {
    return a * b;
}

这就是为什么不能将 mfp 类型的对象添加到 fp 类型的 vector 中的原因。

编辑:起作用的是

struct mult {
    static double fun(double a, double b) { return a * b; }
};

fp f = &mult::fun;
functions1.push_back(f);

通过使成员函数成为static,它不再绑定(bind)到对象。

functions1.push_back(mfp);

可能是一个拼写错误,因为 mfp 是 typedef,而不是函数对象 f...

编辑 2:还有一个选项可以使用 std::bind 将第一个隐藏参数绑定(bind)到特定对象。

例如使用您的原始(非静态)成员函数:

mult obj;
fnc temp = std::bind(&mult::fun, &obj, std::placeholders::_1, std::placeholders::_2);
functions.push_back(temp);

关于c++ - std::function 如何使指向成员函数的指针起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58592046/

相关文章:

c++ - 如何使用 CMake 链接多个库

c++ - 如何在qt中安装Symbian

c++ - 在 C++ 中将类型的容器作为字段是个坏主意吗?

c# - C++ 和 C# 调用 CryptEncrypt 和 CryptDecrypt

c++ - 为 Windows CE 编译的 FreeImage.dll?

c++ - 嵌入数据的多种类型

c++ - 如何在 qt 标签中显示 em dash 字符?

c++ - 方便的标志处理,其中所有标志都不能适应 64 位

C++ GDI+ 选择调色板

c++ - 在 C++ 中的 += 运算符函数内调用 Operator+ 函数