C++11中能否用bind替代lambda调用集合元素的成员方法?
用C++11的std::bind替代lambda调用成员函数的解决方案
嘿,这个问题刚好能帮你理清C++11里std::bind和成员函数绑定的细节,咱们一步步来拆解:
为什么你的bind(&Foo::print)会失败?
成员函数Foo::print()本质上隐含了一个this指针参数——它必须依附于某个Foo实例才能调用。你直接写bind(&Foo::print)的时候,没有给这个this参数留位置或者提供实例,导致生成的函数对象和perform要求的std::function<void(Foo&)>类型不匹配,自然无法运行。
两种用bind(或结合mem_fn)替代lambda的方法
方法1:用std::placeholders给this参数占位
你需要告诉std::bind:“我后面会传入一个Foo实例作为this指针”,这时候就用到了占位符:
#include <iostream> #include <vector> #include <functional> #include <algorithm> using namespace std; class Foo { public: void print() { cout << "hello" << endl; } }; class Helper { private: vector<Foo> v; public: Helper() : v(5) { } void perform(std::function<void(Foo&)>&& f) { for_each(v.begin(), v.end(), f); } }; int main() { Helper r; // 用bind配合占位符,指定第一个参数作为print的this指针 r.perform(bind(&Foo::print, placeholders::_1)); r.perform([](Foo& f) {f.print();}); // 原lambda写法 }
这里placeholders::_1表示:当绑定后的函数对象被调用时,第一个传入的参数(也就是for_each遍历的每个Foo&)会被当作this指针传递给print方法,完美匹配perform的要求。
方法2:结合std::mem_fn简化成员函数适配
std::mem_fn是C++11专门为成员函数设计的适配器,它能把成员函数指针直接转换成一个接受实例作为参数的函数对象,不需要额外的占位符:
// 在main函数里替换成这个写法 r.perform(mem_fn(&Foo::print));
mem_fn(&Foo::print)生成的函数对象,在被调用时会自动把传入的Foo&作为this指针去调用print,同样符合perform的参数要求,写法比bind更简洁。
对比lambda和bind/mem_fn
- lambda是C++11引入的更灵活的可调用对象写法,直观易懂,你原来的lambda写法其实是最清晰的;
std::bind更适合提前绑定部分参数的场景,而这里只是适配成员函数,用占位符稍显繁琐;std::mem_fn则是专门针对成员函数的适配工具,在需要把成员函数当作普通函数对象使用时非常方便。
总的来说,你完全可以用bind(配合占位符)或者mem_fn替代lambda实现需求,这也能帮你理解C++11里函数适配器和可调用对象的设计思路。
内容的提问来源于stack exchange,提问作者greywolf82
相关产品推荐
相关产品推荐

