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

如何在C++类方法内部使用std::bind绑定自身成员函数

类方法内部绑定自身带参函数的问题解决

我需要在类方法内部绑定带指定参数的自身函数,用于调度回调——现有一个基于std::chrono时间标识到std::function<void(void)>的multimap调度器,希望方法执行后,调度自身在未来再次调用,因此要创建自身的std::bind对象存入multimap。但始终写不对语法,比如以下代码:

#include <functional>
#include <iostream>

class x {
public:
  void testBind(char y);
};

void x::testBind(char y) {
    std::cout<<"Blah! " << y << "\n";
    auto boundItself = std::bind(&x::testBind, &x, std::placeholders::_1);

    boundItself('h');
}

编译时会报错:

error C2275: 'x': expected an expression instead of a type

问题原因

你出错的核心是std::bind的第二个参数传错了:在类成员函数内部,要获取当前实例的指针,必须用this,而不是&x——x是类的类型名,&x代表的是类型的地址,不是具体实例的地址,这不符合std::bind绑定成员函数的要求(绑定成员函数时,第二个参数必须是该类的实例指针/引用)。

对比cppreference上的示例:

struct Foo {
    void print_sum(int n1, int n2)
    {
        std::cout << n1+n2 << '\n';
    }
    int data = 10;
};
int main()
{
    using namespace std::placeholders; 

    Foo foo;
    auto f3 = std::bind(&Foo::print_sum, &foo, 95, _1);
    f3(5);

  return 0;
}

这个示例能运行,是因为它在main函数里传入了具体实例的地址&foo;而你在成员函数内部,当前实例的指针就是this,直接用它即可。

修正后的代码

基础绑定(保留参数占位符)

先修正基础的绑定逻辑,让boundItself能正常调用:

#include <functional>
#include <iostream>

class x {
public:
  void testBind(char y);
};

void x::testBind(char y) {
    std::cout<<"Blah! " << y << "\n";
    // 用this代替&x,获取当前实例的指针
    auto boundItself = std::bind(&x::testBind, this, std::placeholders::_1);

    boundItself('h');
}

// 测试调用
int main() {
    x obj;
    obj.testBind('a');
    return 0;
}

适配调度需求(绑定为无参std::function<void(void)>)

如果要适配你的调度器(需要存入std::function<void(void)>类型的回调),可以固定参数,生成无参的可调用对象:

#include <functional>
#include <iostream>
#include <map>
#include <chrono>

class x {
public:
  void testBind(char y) {
      std::cout<<"Blah! " << y << "\n";
      
      // 绑定当前实例+固定参数,得到无参的可调用对象
      auto boundSelf = std::bind(&x::testBind, this, 'h');
      // 存入调度multimap:key为调度时间,value为无参回调
      std::multimap<std::chrono::steady_clock::time_point, std::function<void(void)>> scheduler;
      auto nextInvokeTime = std::chrono::steady_clock::now() + std::chrono::seconds(1);
      scheduler.emplace(nextInvokeTime, boundSelf);
      
      // 模拟调度执行(实际场景中由调度器在时间到达后触发)
      if (!scheduler.empty()) {
          scheduler.begin()->second();
      }
  }
};

int main() {
    x obj;
    obj.testBind('a');
    return 0;
}

这样绑定后的boundSelf就是一个无需传入参数的可调用对象,完全符合std::function<void(void)>的要求,可以直接存入你的调度multimap中。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 12:10:28