摘自:深入應用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的使用例子
- 使用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;
}
- 使用組合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;
}