c++11 bind()妙用
c++11中的bind()函数是个好东西,尤其在适配两个“参数不同的函数” 问题方面发挥着不可替代的作用。
可以看作一个通用的函数适配器。
std::function<void (int)> callback = std::bind(&A::a_callback, this, std::placeholoders::_1, "A Test Callback")
bind()接受一个可调用对象A::a_callback(有两个参数,一个参数传到外部,给新生成的调用对象callback ),生成一个新的可调用对象callback来“适应” 原调用对象A::a_callback的参数列表。这样就把原对象的2个参数,适配到了新的对象的一个参数。
举例说明:
class ImuDriverApp { public: ImuDriverApp(int32_t id, const std::string& ns) : bus_(id, ns) { } void Setup() { imu_sub1_ = bus_.AddReader<holo::common::Imuf>("TestImu1"); imu_sub2_ = bus_.AddReader<holo::common::Imuf>("TestImu2"); //auto reader = std::bind(&ImuDriverApp::ImuCallback, this, std::placeholders::_1); //imu_sub1_.SetOnDataAvailableCallback(std::bind(&ImuDriverApp::ImuCallback, this, std::placeholders::_1, std::string)); //imu_sub2_.SetOnDataAvailableCallback(std::bind(&ImuDriverApp::ImuCallback, this, std::placeholders::_1, std::string)); imu_sub1_.SetOnDataAvailableCallback(std::bind(&ImuDriverApp::ImuCallback, this, std::placeholders::_1, "TestImu1")); imu_sub2_.SetOnDataAvailableCallback(std::bind(&ImuDriverApp::ImuCallback, this, std::placeholders::_1, "TestImu2")); BusType::AsyncSpin(1); while (BusType::IsRunning()) { sleep(1); std::cout<<"ImuDriverApp::Setup"<<std::endl; } } private: void ImuCallback(const holo::common::Imuf& sample, std::string topic) { auto timestamp = sample.GetTimestamp().ToNsec(); auto angular = sample.GetAngularVelocity<holo::geometry::Point3f>(); auto linear = sample.GetLinearAcceleration<holo::geometry::Point3f>(); std::cout << "Timestamp: " << timestamp << std::endl; std::cout << "Angular velocity: " << angular[0] << ", " << angular[1] << ", " << angular[2] << std::endl; std::cout << "linear acceleration: " << linear[0] << ", " << linear[1] << ", " << linear[2] << std::endl; #if 1 if(topic == "TestImu1") { std::cout<<"current topic:"<<"TestImu1"<<std::endl; imu_sub1_.ResetOnDataAvailableCallback(); } else if(topic == "TestImu2") { std::cout<<"current topic:"<<"TestImu2"<<std::endl; imu_sub2_.ResetOnDataAvailableCallback(); } else { std::cout<<"No right topic"<<std::endl; } #endif } private: BusType bus_; BusType::ReaderType<holo::common::Imuf> imu_sub1_; BusType::ReaderType<holo::common::Imuf> imu_sub2_; }; int main(int argc, char** argv) { BusType::Initialize(argc, argv, std::string("imu_subscriber")); signal(SIGINT, BusType::SignalHandler); ImuDriverApp driver(1, ""); driver.Setup(); return 0; }
注意:
imu_sub1_.SetOnDataAvailableCallback(std::bind(&ImuDriverApp::ImuCallback, this, std::placeholders::_1, "TestImu1")); //auto callback = std::bind(&ImuDriverApp::ImuCallback, this, std::placeholders::_1, "TestImu1"); //imu_sub1_.SetOnDataAvailableCallback(callback);
class Reader的成员函数
void SetOnDataAvailableCallback(std::function<void(ValueType const&)> callback)
的参数,是一个只有一个参数的可调用对象,但是ImuDriver App::ImuCallback是个有两个参数的可调用对象,通过 std::bind()将两个函数做好适配,两个函数共有的参数是第一个占位符代表的参数,也就是第一个参数。第二个参数是ImuCallback写死的参数,他传不到auto callback这个只有一个参数的可调用对象当中,这个callback对象也只能传递一个参数到ImuCallback的第一个参数中。