std::function是一組函數對象包裝類的模板,實現了一個泛型的回調機制。function與函數指針比較相似,優點在於它允許用戶在目標的實現上擁有更大的彈性,即目標既可以是普通函數,也可以是函數對象和類的成員函數,而且可以給函數添加狀態。 聲明一個function時,需要給出所包裝的函數對象的 ...
std::function是一組函數對象包裝類的模板,實現了一個泛型的回調機制。function與函數指針比較相似,優點在於它允許用戶在目標的實現上擁有更大的彈性,即目標既可以是普通函數,也可以是函數對象和類的成員函數,而且可以給函數添加狀態。
聲明一個function時,需要給出所包裝的函數對象的返回值類型和各個參數的類型。比如,聲明一個function,它返回一個bool類型並接受一個int類型和一個float類型的參數,可以像下麵這樣:
function<bool (int, float)> f;
下麵簡要介紹一下function的比較重要的幾個介面。
function();
預設構造函數,創建一個空的函數對象。如果一個空的function被調用,將會拋出一個類型為bad_function_call的異常。
template
這個泛型的構造函數接受一個相容的函數對象,即這樣一個函數或函數對象,它的返回類型與被構造的function的返回類型或者一樣,或者可以隱式轉換,並且它的參數也要與被構造的function的參數類型或者一樣,或者可以隱式轉換。
註意,也可以使用另外一個function實例來進行構造。這樣做,並且function g為空,則被構造的function也為空。使用空的函數指針和空的成員函數指針也會產生空的function。如果這樣做,並且function g為空,則被構造的function也為空。使用空的函數指針和空的成員函數指針也會產生空的function。
template
這個構造函數與前一個類似,但它接受的函數對象包裝在一個reference_wrapper中,用以避免通過值來傳遞而產生函數或函數對象的一份拷貝。這同樣要求函數對象相容於function的簽名。
function& operator=(const function& g);
賦值操作符保存g中的函數或函數對象的一份拷貝;如果g為空,被賦值的函數也將為空。
template
這個泛型賦值操作符接受一個相容的函數指針或函數對象。
註意,也可以用另一個 function 實例(帶有不同但相容的簽名)來賦值。這同樣意味著,如果g是另一個function實例且為空,則賦值後的函數也為空。賦值一個空的函數指針或空的成員函數指針也會使function為空。
bool empty() const;
這個成員函數返回一個布爾值,表示該function是否含有一個函數或函數對象。如果有一個目標函數或函數對象可被調用,它返回 false 。因為一個function可以在一個布爾上下文中測試,或者與0進行比較,因此這個成員函數可能會在未來版本的庫中被取消,你應該避免使用它。
void clear();
這個成員函數清除 function, 即它不再關聯到一個函數或函數對象。如果function已經是空的,這個調用沒有影響。在調用後,function肯定為空。令一個function為空的首選方法是賦0給它;clear 可能在未來版本的庫中被取消。
result_type operator()(Arg1 a1, Arg2 a2, ..., ArgN aN) const;
調用操作符是調用function的方法。你不能調用一個空的 function ,那樣會拋出一個bad_function_call的異常。調用操作符的執行會調用function中的函數或函數對象,並返回它的結果。
代碼1
void hello1(){
cout<<"hello1()"<<endl;
}
void hello2(string str){
cout<<"hello2(string str)"<<endl;
}
int sum(int a ,int b){
return a+b;
}
int main(){
function<void()> func1=hello1;或
function<void()> func11(hello1);
func1(); //=》 func1.operator() =>hello1()
function<void(string)> func2=hello2;
func2("hello");// =>func2.operator()("hello")=>hello2("hello")
function<int(int,int)> func3=sum;
int ret = func3(20,30);// int ret = func3.operator()(20,30) =>sum(20,30)
//通過函數類型實例化function,通過function調用operator()函數的時候,需要根據函數類型傳入相應的參數
}
代碼2
class Test{
public:
void say(string str){cout<str<<endl;}
}
int main(){
//註意第一參數是一個隱藏的參數,Test 指針
function<void (Test * ptest , string str)> func=&Test::say;
func(&Test(),"hello Call Say()");
}
代碼3,使用示例
#include <iostream>
#include <string>
#include <map>
#include <functional>
using namespace std;
void showNew() {
string str = "<新建>";
cout << str << endl;
}
void showFile() {
string str = "<文件>";
cout << str << endl;
}
void showAdd() {
string str = "<添加>";
cout << str << endl;
}
void showClose() {
string str = "<關閉>";
cout << str << endl;
}
void showExit() {
string str = "<退出>";
cout << "<退出>" << endl;
}
int main() {
map<int, function<void()>> mp;
function<void()> f1 = showNew;
function<void()> f2 = showFile;
function<void()> f3 = showAdd;
function<void()> f4 = showClose;
mp.insert(pair<int, function<void()>>(1, f1));
mp.insert(pair<int, function<void()>>(2, f2));
mp.insert(pair<int, function<void()>>(3, f3));
mp.insert(pair<int, function<void()>>(4, f4));
for (int i = 1; i <= 4; i++) {
mp.find(i)->second();
}
system("pause");
return 0;
}