You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++移动成员函数实现后std::function绑定错误求助

问题解决:非静态成员函数地址与std::bind的正确用法

问题根源

非静态成员函数自带隐藏的this指针,因此不能直接将其地址作为普通函数指针传递,必须绑定对应的类实例才能正常调用;使用std::bind时,必须明确传入实例(指针或引用)并正确指定参数占位符,否则会触发参数数量不匹配的错误。


方案1:正确使用std::bind + std::function

假设你的类定义和接收函数对象的run函数如下:

头文件 type.h

namespace Tom {
    class Car {
    public:
        void drive(int speed);
    };
}

实现文件 type.cpp

#include "type.h"
#include <iostream>

void Tom::Car::drive(int speed) {
    std::cout << speed << " ";
}

主程序正确写法

#include <iostream>
#include <functional>
#include "type.h"

void run(std::function<void(int)> func) {
    func(50);
    func(100);
}

int main() {
    Tom::Car my_car;
    // 绑定类实例指针和成员函数,std::placeholders::_1对应后续传入的speed参数
    auto bound_drive = std::bind(&Tom::Car::drive, &my_car, std::placeholders::_1);
    run(bound_drive);
    return 0;
}

关键:std::bind的第一个参数是成员函数的地址,第二个参数是类实例的指针(或用std::ref(my_car)传递引用),占位符_1表示调用时传入的第一个参数会传递给drive的speed参数。


方案2:不使用std::function的实现

如果不想依赖std::function,可以用两种原生C++写法:

子方案2.1:Lambda表达式+模板函数

修改run为模板函数,支持任意可调用对象:

#include <iostream>
#include "type.h"

// 模板函数,兼容所有可调用类型
template<typename Callable>
void run(Callable func) {
    func(50);
    func(100);
}

int main() {
    Tom::Car my_car;
    // Lambda捕获类实例,直接调用成员函数
    run([&my_car](int speed) {
        my_car.drive(speed);
    });
    return 0;
}

这种写法简洁直观,无需额外绑定,直接通过lambda捕获实例并转发参数。

子方案2.2:成员函数指针模板

直接传递类实例和成员函数指针:

#include <iostream>
#include "type.h"

// 模板函数,接收类实例和成员函数指针
template<typename T>
void run(T& obj, void (T::*drive_func)(int)) {
    // 成员函数指针调用语法:(对象.*函数指针)(参数)
    (obj.*drive_func)(50);
    (obj.*drive_func)(100);
}

int main() {
    Tom::Car my_car;
    run(my_car, &Tom::Car::drive);
    return 0;
}

这种写法完全不依赖标准库的函数绑定工具,直接利用C++原生的成员函数指针语法。


内容的提问来源于stack exchange,提问作者Senor Maldona

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 05:31:23