如何让std::bind关联类显式构造实例的成员函数指针?
问题概述
使用std::bind绑定EkfFilter类的成员函数odometryCallback时,编译器抛出错误:use of deleted function,错误指向EkfFilter的拷贝构造函数。原因是EkfFilter定义了显式构造函数,编译器未生成默认拷贝构造,而std::bind默认会尝试拷贝传入的类实例。
原因分析
std::bind在绑定成员函数时,若直接传入类实例对象,会默认拷贝该对象存储到生成的绑定器中。但EkfFilter因存在显式构造函数,编译器自动删除了默认拷贝构造函数,导致拷贝操作失败,触发上述错误。
解决方案
提供两种可行的解决方式:
方法1:用std::ref传递类实例引用
修改setupOdometryCallback中的std::bind调用,用std::ref包裹filter参数,让std::bind存储实例的引用而非拷贝对象:
return std::bind(&EkfFilter::odometryCallback, std::ref(filter), std::placeholders::_1, odomTopicName, poseCallbackData, twistCallbackData);
说明:
std::ref会将对象包装为引用类型,避免拷贝操作,绕过拷贝构造函数的限制。- 必须保证
EkfFilter实例(main函数中的ekf)的生命周期长于返回的OdomFunc对象(odomF),否则会出现悬空引用,引发未定义行为。当前代码中ekf在main栈中,odomF也在同栈帧,生命周期满足要求。
方法2:使用Lambda表达式替代std::bind
用Lambda表达式直接捕获filter的引用,调用成员函数,代码更直观且灵活:
return [&filter, odomTopicName, poseCallbackData, twistCallbackData](const nav_msgs::Odometry::ConstPtr& msg) { filter.odometryCallback(msg, odomTopicName, poseCallbackData, twistCallbackData); };
说明:
- Lambda捕获
filter的引用,直接调用成员函数,无需依赖std::bind的拷贝逻辑。 - 同样需要保证
filter的生命周期长于返回的std::function对象。当前场景下只能用引用捕获,因为EkfFilter不支持拷贝。
注意事项
- 两种方法的核心都是避免拷贝
EkfFilter实例,转而使用引用关联原对象。 - 若
odometryCallback是const成员函数,需将捕获的filter改为const&类型,确保类型匹配。
内容的提问来源于stack exchange,提问作者user19865469
相关产品推荐
相关产品推荐

