https://www.cnblogs.com/bencai/p/9124654.html //關於function
https://www.cnblogs.com/geloutingyu/p/8335230.html //關於lambda、bind
序
爲編寫更通用的代碼,將數據類型與方法、類分離,這就是泛型編程思想。
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
——換言之,參數列表裏的參數如何傳參,與捕獲列表裏的局部變量如何傳參,是兩回事。
可以看到,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修飾。如果不加,會出現以下錯誤:
因此筆者猜測,傳值後,編譯器將該值加了const修飾。
關於捕獲的更多細節、返回值、bind、lambda的常見應用,可以參考第二條引用鏈接。在此感謝作者的分享~
目前正在開發的jojo_webserver裏也使用了function、lambda以及bind,過段時間寫好博客發上來。