一:function定義
- 類模闆 std::function是一種通用的多态函數包裝器,它的執行個體可以對任何可以調用的目标實體進行存儲,複制和調用操作。
- 簡單的來說:C++中有幾種可調用對象:函數,指針,lambda表達式,bind建立的對象,以及重載了調用運算符的類,function是一種類型,這種類型可以将上述不同類型對象,整合到一個類型中。
- 它是對C++中現有的可調用實體的一種類型安全的包裹(相對來說,函數指針的調用不是類型安全的)
二:function執行個體
1:定義一個模闆 : typedef function<int(int)> Funtional
2: 此模闆可以包裝接收:普通函數,lambda函數,仿函數,靜态成員函數,成員函數
#include<iostream>
#include<string>
#include<functional>
using namespace std;
// 聲明一個模闆
typedef function<int(int)> Functional;
// 普通函數
int testFunc(int a) {
return a+1;
}
// lambda expression
auto lambda = [](int a)->int
{
return a + 2;
};
// functor仿函數
class Functor
{
public:
int operator()(int a) {
return a + 3;
}
};
// 類的成員函數和類的靜态成員函數
class CTest {
public:
int Func(int a) {
return a + 4;
}
static int SFunc(int a) {
return a + 5;
}
};
int main() {
// 封裝普通函數
Functional obj = testFunc;
cout << "普通函數:" << obj(0) << endl;
// 封裝lambda表達式
obj = lambda;
cout << "lambda函數:" << obj(1) << endl;
// 封裝仿函數
Functor fuctor;
obj = fuctor;
// 封裝類的成員函數和類的靜态成員函數
CTest t;
// 綁定類的成員函數,一定要傳遞對象給bind的第二個參數,可以是類對象,也可以是類對象的指針(這是因為成員函數有一個預設的this指針)
obj = std::bind(&CTest::Func, &t, placeholders::_1);
cout << "成員函數函數:" << obj(3) << endl;
// 綁定靜态的成員函數
obj = CTest::SFunc;
cout << "靜态成員函數函數:" << obj(4) << endl;
}
案例2:定義一個 function類型,并作為形參傳入類的成員函數,從Function 包裝的:函數對象,全局函數,lambda表達式,函數指針這幾種方式中,找到一種方式:滿足形參指派給類的成員變量 ------》(先說結論:隻有lambda表達式可以實作:捕獲對象,進而實作修改類的成員變量)
// main.cpp
#include "test.h"
#include<iostream>
#include<string>
#include<Functional>
using namespace std;
void MyTest::test(callback_ callback) {
cout << "test call m_i = " << this->m_i << endl;
}
// 全局函數
void func(int i) {
cout << "global func call m_i = " << i<< endl;
}
// lambda表達式
void lambda() {
MyTest mytest;
// lambda表達式:捕獲對象 mytest引用,修改成員變量: m_i
auto lambda = [&mytest](int i) {
mytest.m_i = i;
cout << "lambda 本體調用後 m_i = " << mytest.m_i << endl;
};
lambda(1);
mytest.test(lambda);
cout << "mytest m_i = " << mytest.m_i << endl;
}
// 函數對象(仿函數)
class FunObj
{
public:
void operator()(int i) {
cout << "func obj call m_i = " << i << endl;
}
};
// 函數指針
void (*fun_pointer)(int i);
int main() {
// lambda 方式:可以捕獲目前對象,通過目前對象修改類的成員變量
// lambda();
// 全局函數方式(失敗,由于function定義的是接收一個參數)(且不能 捕獲目前對象,就不能通過目前對象修改類的成員變量)
/*MyTest mytest1;
callback_ _callback = func;
_callback(1);
mytest1.test(_callback);*/
// 仿函數的方式(失敗,由于function定義的是接收一個參數)(且不能 捕獲目前對象,就不能通過目前對象修改類的成員變量)
/*MyTest test;
callback_ _callback = FunObj();
_callback(1);
test.test(_callback);*/
// 函數指針方式 (待定)
MyTest test1;
callback_ _callback = fun_pointer;
// _callback(1);
// fun_pointer(1);
test1.test(_callback);
}
// test.h
#pragma once
#include<functional>
using callback_ = std::function<void(int)>;
class MyTest
{
public:
int m_i = 0;
void test(callback_ callback);
private:
};