如何将vector中对象的成员函数绑定到std::function?
如何绑定vector中次级配置对象的get方法到std::function
问题场景
现有主配置类config和次级配置类secConfig,config包含一个secConfig对象的vector,需要将该vector中最后一个(也是唯一一个)secConfig的get_data方法绑定到std::function<double()>,加入到测试用的getvals容器中,实现和config::getData一致的调用方式。
解决方案
方法1:使用Lambda表达式(最简洁直观)
Lambda可以直接捕获目标config对象,链式调用获取内部vector最后一个元素的get_data,完美适配std::function<double()>的签名:
// 替换原注释的绑定代码 getvals.push_back([&mainConfig]() { return mainConfig.getVecData().back().get_data(); }); // 调用测试 cout << "Secondary (vectorized) config data : " << getvals[1]() << endl;
方法2:给config类添加封装方法(更符合面向对象封装性)
如果希望避免直接暴露内部vector的操作,可以给config类新增一个方法,直接返回最后一个secConfig的data值,绑定方式和getData完全一致:
首先修改config类的定义和实现:
// config类public部分新增方法 double getLastSecData() { if (secConfigs.empty()) { // 可根据需求返回默认值或抛出异常 return 0.0; } return secConfigs.back().get_data(); }
然后绑定的时候直接复用bind逻辑:
getvals.push_back(bind(&config::getLastSecData, &mainConfig)); cout << "Secondary (vectorized) config data : " << getvals[1]() << endl;
方法3:分步使用bind(不推荐,可读性差)
如果一定要用纯bind实现,需要分步绑定各环节的成员函数,但写法繁琐且可读性低:
auto get_vec = bind(&config::getVecData, &mainConfig); auto get_last_sec = bind(&vector<secConfig>::back, get_vec()); getvals.push_back(bind(&secConfig::get_data, get_last_sec));
完整修改后的示例代码
#include <iostream> #include <vector> #include <functional> using namespace std; class secConfig{ private: double data; public: secConfig(double); double get_data(); }; secConfig::secConfig(double indata){ data = indata; } double secConfig::get_data(){ return data; } class config{ private: std::vector<secConfig> secConfigs; double normalData; public: config(double, vector<secConfig>); double getData(); vector<secConfig> getVecData(); // 新增封装方法 double getLastSecData(); }; config::config(double inData, vector<secConfig> inVec){ normalData = inData; secConfigs = inVec; } double config::getData(){ return normalData; } vector<secConfig> config::getVecData(){ return secConfigs; } double config::getLastSecData(){ if (secConfigs.empty()) { return 0.0; } return secConfigs.back().get_data(); } int main(int argc, char const *argv[]) { secConfig initial(66.6); vector<secConfig> inConfigs; inConfigs.push_back(initial); cout << "Inconfig raw data: " << initial.get_data() << endl; cout << "Inconfig vector data: " << inConfigs.back().get_data() << endl; config mainConfig(55.5, inConfigs); cout << "Main config raw data: " << mainConfig.getData() << endl; cout << "Main config internal vec data: " << mainConfig.getVecData().back().get_data() << endl; vector<function<double()>> getvals; // 绑定主配置方法 getvals.push_back(bind(&config::getData, &mainConfig)); cout << "Main config bound data: " << getvals[0]() << endl; // 方法1:Lambda方式绑定 getvals.push_back([&mainConfig]() { return mainConfig.getVecData().back().get_data(); }); cout << "Secondary (lambda) config data : " << getvals[1]() << endl; // 方法2:调用封装方法绑定 getvals.push_back(bind(&config::getLastSecData, &mainConfig)); cout << "Secondary (encapsulated) config data : " << getvals[2]() << endl; return 0; }
说明
- 原代码中尝试的
bind(&config::getVecData::back::get_data, &mainConfig)写法不可行,因为bind无法直接解析链式的成员函数调用,Lambda则可以自由处理任意复杂的调用逻辑。 - 新增封装方法的方式更符合面向对象的设计原则,隐藏了内部vector的细节,同时简化了绑定逻辑。
内容的提问来源于stack exchange,提问作者Douglas B
相关产品推荐
相关产品推荐

