【读书笔记】【深入应用C++11】1.5 std::function和bind绑定器

摘自:深入应用C++11:代码优化与工程级应用
#1.5.1 可调用对象
在C++98/03中,可调用对象包括以下几种:

  • 函数指针
  • 具有opterator()成员函数的类对象(仿函数)
  • 可被转换为函数指针的类对象
  • 类成员(函数)指针
//仿函数
class Foo
{
public:
	void operator()(void)
	{
		cout<<"operator()"<<endl;
	}
};
Foo foo;
foo();
//可被转换为函数指针的类对象
class Bar
{
public:
	static void func(void)
	{
		cout<<"func()"<<endl;
	}
	using fr_t=void (*) (void);

	operator fr_t(void)
	{
		return func;
	}
};
Bar bar;
bar();
//类成员(函数)指针
class Person
{
public:
	int id=100;
	void func(void)
	{
		cout<<"func()"<<endl;
	}
};
void (Person::*func_ptr)(void)=&Person::func;//类成员函数指针
	
Person person;
(person.*func_ptr)();

int Person::*id_ptr=&Person::id;//类成员变量指针
cout<<person.*id_ptr<<endl;

在C++98/03中,保存或传递可调用对象的方法十分繁琐。
在C++11中,提供了std::function和std::bind统一了可调用对象的各种操作。
#1.5.2 可调用对象包装器–std::function
std::function是可调用对象的包装器。它是一个类模板可以容纳除类成员(函数)指针之外的所有可调用对象。
它的功能等同于函数指针,可以保存函数、函数对象、函数指针等。std::function主要应用在回调函数。

//绑定到函数
void func(void)
{
	cout<<__FUNCTION__<<endl;
}
function<void(void)> func_ptr=func;
func_ptr();
//绑定到类静态成员函数
class Person
{
public:
	static void Count(void)
	{
		cout<<"Count"<<endl;
	}
};
function<void(void)> func_ptr=Person::Count;
func_ptr();
//绑定到仿函数
class Person
{
public:
	void operator()(int id)
	{
		cout<<"Id:"<<id<<endl;
	}
};
Person person;
function<void(int)> func_ptr=person;
func_ptr(123);
//绑定到可转换为函数指针的类对象
class Bar
{
public:
	static void func(void)
	{
		cout<<"func()"<<endl;
	}
	using fr_t=void (*) (void);

	operator fr_t(void)
	{
		return func;
	}
};
Bar bar;
function<void(void)> func_ptr=bar;
func_ptr();
	

#1.5.3 std::bind绑定器
std::bind用来将可调用对象和其参数一起绑定。绑定后的结果可以使用std::function保存。如:

#include <stdlib.h>
#include <functional>
#include <iostream>
void output(int x, int y)
{
	std::cout << x << " " << y << std::endl;
}

int main(void)
{
	std::function<void(void)> func_ptr = std::bind(output, 1, 2);
	func_ptr(); //输出:1 2
	std::function<void(int)> func1_ptr = std::bind(output, std::placeholders::_1, 2);
	func1_ptr(1); //输出:1 2
	system("pause");
	return 0;
}

std::bind可以直接绑定函数的所有参数,也可以仅绑定部分参数。在绑定部分参数的时候,通过使用std::placeholders来决定空位参数将会属于调用发生时的第几个参数。

std::bind的使用例子

  1. 使用bind简化和增强bind1st和bind2nd
    如:查找小于5的元素的个数。
#include <stdlib.h>
#include <functional>
#include <vector>
#include <algorithm>
#include <iostream>
int main(void)
{
	std::vector<int> vect = { 0,1,2,3,4,5,6,7,8,9 };
	auto less_func = std::bind(std::less<int>(),std::placeholders::_1, 5);
	int count = std::count_if(vect.begin(),vect.end(),less_func);
	std::cout << count << std::endl;
	system("pause");
	return 0;
}
  1. 使用组合bind函数
    bind还可以组合多个函数。例如要找出集合中大于5小于10的元素个数:
#include <stdlib.h>
#include <functional>
#include <vector>
#include <algorithm>
#include <iostream>
int main(void)
{
	std::vector<int> vect = { 0,1,2,3,4,5,6,7,8,9 };
	auto big_func = std::bind(std::less<int>(), 5, std::placeholders::_1);
	auto less_func = std::bind(std::less<int>(), std::placeholders::_1, 10);
	auto and_func = std::bind(std::logical_and<bool>(), big_func, less_func);
	int count = std::count_if(vect.begin(),vect.end(), and_func);
	std::cout << count << std::endl;
	system("pause");
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章