天天看點

C++11中的一些泛型程式設計思想——函數指針、function、lambda序函數指針functionlambda

https://www.cnblogs.com/bencai/p/9124654.html //關于function

https://www.cnblogs.com/geloutingyu/p/8335230.html //關于lambda、bind

泛型程式設計思想

  • 函數指針
  • function
  • lambda

為編寫更通用的代碼,将資料類型與方法、類分離,這就是泛型程式設計思想。

C++ 的三大面向對象特性:封裝、繼承、多态。它們分别保證了安全性、可複用性以及特性。

偷懶是人類的重要生産力。

從類的繼承、template、函數指針,再到function、lambda,均是為了踐行泛型程式設計思想,讓偷懶更成功。

下面給出幾個常用、淺顯、直覺的例子,學習函數指針、function、lambda的使用。

函數指針

#include<iostream>
using namespace std;

class Foo
{
public:
	void foo(int i) { cout << "Foo:" << i << endl; }
};
void foo(int i) { cout << i << endl;}

int main()
{
	void (*func1) (int x);
	func1 = foo;
	func1(1);

	void (Foo::*func2) (int);
	func2 = Foo::foo;
	Foo f;
	(f.*func2)(2);//一個很别扭但正确的調用方式,成員函數必須綁定到一個對象執行個體上
}
           

main函數裡的第一部分是普通函數的函數指針的使用。第二部分是類成員函數的函數指針的使用。

function

https://www.cnblogs.com/bencai/p/9124654.html

lambda

lambda是一種一次性的匿名函數,有定義而無函數名,與普通函數性能一樣強。

形式為:

[捕獲清單](參數清單) ->傳回值{函數體}

主要說說

捕獲清單

1、預設情況下,即捕獲字段為 [] 時,lambda表達式是不能通路任何外部變量的,即表達式的函數體内無法通路目前作用域下的變量。

2、

=

函數體内可以使用 Lambda 所在範圍内所有可見的局部變量(包括 Lambda 所在類的 this),并且是值傳遞方式(相當于編譯器自動為我們按值傳遞了所有局部變量)。

3、

&

函數體内可以使用 Lambda 所在範圍内所有可見的局部變量(包括 Lambda 所在類的 this),并且是引用傳遞方式(相當于是編譯器自動為我們按引用傳遞了所有局部變量)。

4、

this

函數體内可以使用 Lambda 所在類中的成員變量。

5、

a

将 a 按值進行傳遞。按值進行傳遞時,函數體内不能修改傳遞進來的 a 的拷貝,因為預設情況下函數是 const 的,要修改傳遞進來的拷貝,可以添加 mutable 修飾符。

6、

&a

将 a 按引用進行傳遞。

7、

a,&b

将 a 按值傳遞,b 按引用進行傳遞。

8、

=,&a,&b

除 a 和 b 按引用進行傳遞外,其他參數都按值進行傳遞。

9、

&,a,b

除 a 和 b 按值進行傳遞外,其他參數都按引用進行傳遞。

下面是一個簡單的捕獲局部變量的例子,學習一下捕獲清單裡的&:

//exp1:
	int test = 1;
	int a = 2;
	int b = 3;
	
	auto func1 = [&](int a, int b) {
		++a;
		++b;
		++test;
		return test + a + b;
	};
	cout << "default capture list, result = " << func1(a, b) << endl;
	cout << "test = " << test << " , a = " << a << " , b = " << b << endl;
           

這裡capture list裡的&符号指的是lambda外部的局部變量按照引用傳值,

這裡的引用不針對參數清單裡的a和b

——換言之,參數清單裡的參數如何傳參,與捕獲清單裡的局部變量如何傳參,是兩回事。

C++11中的一些泛型程式設計思想——函數指針、function、lambda序函數指針functionlambda

可以看到,a和b的值仍然是2和3,test的值從1變為2。

下面是一個簡單的捕獲局部變量的例子,學習一下捕獲清單裡的=:

int test = 1;
	int a = 2;
	int b = 3;
	
	auto func2 = [=](int a, int b) mutable{
		++a;
		++b;
		++test;
		return a + b;
	};

	cout << "default capture list, result = " << func2(a, b) << endl;
	cout << "test = " << test << " , a = " << a << " , b = " << b << endl;
           

這裡必須加mutable 正如本節5所說,如果是傳值且想改變該值,必須用mutable修飾。如果不加,會出現以下錯誤:

C++11中的一些泛型程式設計思想——函數指針、function、lambda序函數指針functionlambda

是以筆者猜測,傳值後,編譯器将該值加了const修飾。

關于捕獲的更多細節、傳回值、bind、lambda的常見應用,可以參考第二條引用連結。在此感謝作者的分享~

目前正在開發的jojo_webserver裡也使用了function、lambda以及bind,過段時間寫好部落格發上來。

繼續閱讀