c++11新特性之std::function、std::bind、std::placeholders、lambda 表达式的使用
结论
1.std::function为函数指针封装,方便调用,std::bind、std::placeholders辅助std::function使用 2.所有的std::function(包括通过std::bind、std::placeholders辅助)都可以使用lambda表达式实现相同效果 3.一般std::bind调用类的成员函数和成员变量时,顺序是:
std::bind(&类::成员函数, &类的实例名, 95, std::placeholders::_1,...);
4.偷懒可以使用auto来取代std::function<…(…)>,例如:
auto f2 = std::bind(f, _3, std::bind(g, _3), _3, 4, 5);
5.可以嵌套智能指针
auto f4 = std::bind(&Foo::print_sum, &foo, 95, _1);
f4(std::make_shared<Foo>(foo));
6.lambda表达式总结 用法:
auto func = [capture] (params) opt -> ret { func_body; };
其中 func 是可以当作 lambda 表达式的名字,作为一个函数使用,capture 是捕获列表,params 是参数表,opt 是函数选项 (mutable 之类), ret 是返回值类型,func_body 是函数体。
[]: 1.[]不捕获任何变量 2.[&]引用捕获,捕获外部作用域所有变量,在函数体内当作引用使用 3.[=]值捕获,捕获外部作用域所有变量,在函数内内有个副本使用(注意这个值是const类型) 修改可通过:
auto f3 = [=]() mutable { return a++; };
4.[=, &a]值捕获外部作用域所有变量,按引用捕获 a 变量 5.[a]只值捕获 a 变量,不捕获其它变量 6.[this]捕获当前类中的 this 指针
示例
所有的std::function(包括通过std::bind、std::placeholders辅助)都可以使用lambda表达式实现相同效果
#include <iostream>
#include <functional>
struct MyStruct
{
int operator()(int a) const{
std::cout << "MyStruct num :" << a << std::endl;
return a;
}
};
class MyClass
{
public:
MyClass() {
}
MyClass(int num) :m_num(num) {
}
~MyClass() {
}
int m_print_number(int num) const {
std::cout << "MyClass num : " << num << std::endl;
return num;
}
int m_num;
};
void print_number(int num) {
std::cout << "num : " << num << std::endl;
}
int main() {
std::function<void(int)> f0 = print_number;
f0(0);
std::function<void(int)> f0_lambda = [](int a) {
print_number(a);
};
f0_lambda(0);
std::function<void()> f1 = std::bind(print_number, 1);
f1();
std::function<void()> f1_lambda = []() {
print_number(1);
};
f1_lambda();
const MyClass myclass2;
std::function<int(const MyClass&, int)> f2 = &MyClass::m_print_number;
f2(myclass2,2);
std::function<int(const MyClass&, int)> f2_lambda = [](const MyClass& myclass, int a) ->int {
return myclass.m_print_number(a);
};
f2_lambda(myclass2, 2);
std::function<int(int)> f2_ = std::bind(&MyClass::m_print_number, myclass2, std::placeholders::_1);
f2_(2);
std::function<int(int)> f2_lambda_ = [&myclass2](int a) ->int {
return myclass2.m_print_number(2);
};
f2_lambda_(2);
std::function<int(int)> f2__ = std::bind(&MyClass::m_print_number, &myclass2, std::placeholders::_1);
f2__(2);
std::function<int(int)> f2_lambda__ = [&myclass2](int a) ->int {
return (&myclass2)->m_print_number(2);
};
f2_lambda__(2);
const MyClass myclass3(3);
std::function<int(const MyClass&)> f3 = &MyClass::m_num;
std::cout << "myclass3 num : " << f3(myclass3) << std::endl;
std::function<int(const MyClass&)> f3_lambda = [](const MyClass& a) ->int {
return a.m_num;
};
std::cout << "myclass3 num : " << f3_lambda(myclass3) << std::endl;
return 0;
}
|