【讀書筆記】【深入應用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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章