天天看點

C++:std::function模闆類一:function定義二:function執行個體三:Functional原理 

一: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;
}
           
C++:std::function模闆類一:function定義二:function執行個體三:Functional原理 
案例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:

};
           
C++:std::function模闆類一:function定義二:function執行個體三:Functional原理 

三:Functional原理 

繼續閱讀