c++11新特性之std::function、std::bind、std::placeholders、lambda 表达式的使用

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);

//二、通过bind存储绑定调用
	std::function<void()> f1 = std::bind(print_number, 1);
	f1();
	std::function<void()> f1_lambda = []() {
		print_number(1);
	};
	f1_lambda();

//三、存储成员函数调用(注意const!!!)
	//1.不指定对象
	const MyClass myclass2;
	std::function<int(const MyClass&, int)> f2 = &MyClass::m_print_number;
	/*int a = */ f2(myclass2,2);
	std::function<int(const MyClass&, int)> f2_lambda = [](const MyClass& myclass, int a) ->int {
		return myclass.m_print_number(a);
	};
	/*int a = */ f2_lambda(myclass2, 2);
	//2.通过bind和placeholders指定了对象
	std::function<int(int)> f2_ = std::bind(&MyClass::m_print_number, myclass2, std::placeholders::_1);
	/*int a = */ f2_(2);
	std::function<int(int)> f2_lambda_ = [&myclass2](int a) ->int {
		return myclass2.m_print_number(2);
	};
	/*int a = */ f2_lambda_(2);
	//3.通过bind和placeholders指定了对象指针
	std::function<int(int)> f2__ = std::bind(&MyClass::m_print_number, &myclass2, std::placeholders::_1);
	/*int a = */ f2__(2);
	std::function<int(int)> f2_lambda__ = [&myclass2](int a) ->int {
		return (&myclass2)->m_print_number(2);
	};
	/*int a = */ f2_lambda__(2);
	
//四、存储数据成员调用
	const MyClass myclass3(3);
	std::function<int(const MyClass&)> f3 = &MyClass::m_num;
	std::cout << "myclass3 num : " << /*int a = */ f3(myclass3) << std::endl;
	//效果同上(const MyClass& == MyClass const&)
	//std::function<int(MyClass const&)> f3_ = &MyClass::m_num;
	//std::cout << "myclass3 num : " << /*int a = */ f3_(myclass3) << std::endl;
	std::function<int(const MyClass&)> f3_lambda = [](const MyClass& a) ->int {
		return a.m_num;
	};
	std::cout << "myclass3 num : " << /*int a = */ f3_lambda(myclass3) << std::endl;

	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值