lambda表示式
在c語言中,對於陣列的初始化,我們可以這樣進行
int arr=
;
允許陣列使用花括號{}
的方式進行初始化,但是在c++98中的vector
陣列以及一些自定義的型別中,這樣初始化還是不被允許的,而c++11對此做出了修正。
他允許verctor
使用花括號{}
的方式對陣列進行初始化.
vector<
int> arr2
;vector<
int> arr3 =
;
再進行初始化的過程中,陣列名和花括號中可以不新增=
。
支援花括號進行初始化的原因:如果想要使用多個物件對列表進行初始化,需給該類(模板類)新增乙個帶有
initializer_list型別
引數的建構函式 和 =運算子的過載。
template
<
class
t>
class
vector
vector
&operator
=(initializer_list tmparr)
size_t size()
t operator
(size_t idx)
private
: t* _arr;
size_t _size;
size_t _capacity;
};
在c++中,當我們建立乙個類,這個類中會預設有六個成員函式。如果在一些特殊的場合下,我們不想讓這些預設的成員函式發生作用,我們在c++98中可以這樣來:
class
date
;
我們可以把不想存在的預設建構函式變成私有成員,並只對預設函式進行宣告不進行實現,這樣在類外就不能進行訪問,就可以去掉這個預設的建構函式了。
但是在c++11中,新增了乙個delete關鍵字,他可以取消掉預設建構函式的作用。就是在該函式宣告加上=delete
即可,該語法指示編譯器不生成對應函式的預設版本,稱=delete修飾的函式為刪除函式。
class
date
;
對應的還有乙個顯示預設函式。在預設函式定義或者宣告時加上=default,從而顯式的指示編譯器生成該函式的預設版本,用=default
修飾的函式稱為顯式預設函式。
class
date
;
c++相比c語言,提出了引用的概念,但是引用只能對乙個已經宣告的物件進行操作,給他乙個別名,引用的變數和引用的實體共用一塊記憶體空間,就相當於指標,只是我們在使用的時候不用像使用指標那樣(*p),寫法簡單。
但是對於那些臨時變數,這時使用引用是不可以的,因為他們本身就沒有名字,是乙個匿名物件。
為了解決這一問題,c++11加入了右值引用的概念,他也是乙個別名,只是他只能對右值進行使用。
int
&& num =
10;
左值,一般就是可以放在=
左邊,並且可以取位址的變數
普通的變數,他們有名字,那麼就可以取位址,就可以作為左值
const 修飾的常量,雖然不可以修改,但是可以取位址,所以說也是左值
函式的返回值是引用型別,那麼也可以認為是左值
變數的引用型別,也是左值
右值,一般認為只能放在=
右邊,或者不能取位址的變數
函式的返回值是乙個臨時變數,那麼就認為這是乙個右值
變數本身就是乙個臨時變數,或者匿名物件,則為右值
int a =10;
const
int& ra1 =10;
const
int& ar2 = a;
而對於const引用而言,他可以引用右值,也可以引用左值。而普通的引用只可以引用左值。
而右值引用只能引用右值,不能引用左值。
在c++11
中,對於拷貝構造的時候,如果所傳的引數是乙個臨時變數,那麼就會使用右值引用的方式進行操作,而emplace_back函式
就是乙個對於臨時變數操作的介面,他可以完成對臨時物件的尾插操作,避免多餘的拷貝。
用基本型別(int,char)來看的話效果不是那麼明顯,使用string型別來看一下關於右值引用
我們可以看到這個過程一共呼叫了兩次拷貝構造,一次是引數的拷貝構造,一次是插入元素時的拷貝構造,這就造成了資料的利用率比較低。
這是因為const 引用既可以引用左值,也可以引用右值,所以對於左值和右值不容易區分。在c++11中使用右值引用,再加乙個函式過載就可以了。
那麼對於右值引用,只需要將他的引數(乙個臨時物件),進行swap交換一下就可以了,避免了賦值的時候再呼叫一次拷貝構造。
vector
(vector
&& tmparr)
vector
&operator
=(vector
&& tmparr)
有時候在做題的時候,經常會看到一些大佬的程式中有這樣的**
sort
(arr.
begin()
, arr.
end(),
(const
int& a,
const
int& b)
->
bool
);
而自己在寫的時候是這樣的,呼叫自己在函式外部寫的仿函式,然後進行排序
bool
(const
int& a,
const
int& b)
sort
(arr.
begin()
, arr.
end(
), cmp)
;
這就是c++11中的lambda表示式,他可以說是乙個匿名函式,在函式的內部宣告 + 使用。
他的格式如下:
[capture-list]
(parameters) mutable -> return-type
關於捕捉列表,他其實就是為了讓我們在使用lambda表示式的時候,如果想要使用當前作用域內的變數,但是又不想讓他變成引數,那麼就可以使用捕捉列表對想要使用的變數進行捕捉
內容意義
[var]
表示值傳遞方式捕捉變數var
[=]表示值傳遞方式捕獲所有父作用域中的變數(包括this)
[&var]
表示引用傳遞捕捉變數var
[&]表示引用傳遞捕捉所有父作用域中的變數(包括this)
[this]
表示值傳遞方式捕捉當前的this指標
lambda表示式與普通函式在彙編中的呼叫方式
可以看到兩種函式的呼叫的方式是相同的,都是call指令
,只是lambda表示式在呼叫的時候,會自己給函式起乙個lambda的名字,然後使用call進行呼叫。
c 11 右值引用
右值引用 是一種復合型別,跟c 的傳統引用很類似。為更準確地區分兩種型別,我們把傳統的c 引用稱為 左值引用 而使用 引用 這一術語時,我們的意思同時包含兩種引用 左值引用和右值引用。右值引用的行為跟左值引用類似,不同之處在於 右值引用可以繫結到臨時量 右值 而 非const的 左值引用卻不能繫結到...
C 11 右值引用
消除兩個物件互動時不必要的物件拷貝,節省運算儲存資源,提高效率。能夠更簡潔明確地定義泛型函式。1.右值引用 int a a 1 here,a is an lvalue 上述的a就是乙個左值。c 11中左值的宣告符號為 為了和左值區分,右值的宣告符號為 printreference const str...
C 11右值引用
c 11中引入的乙個非常重要的概念就是右值引用。理解右值引用是學習 移動語義 move semantics 的基礎。而要理解右值引用,就必須先區分左值與右值。對左值和右值的乙個最常見的誤解是 等號左邊的就是左值,等號右邊的就是右值。左值和右值都是針對表示式而言的,左值是指表示式結束後依然存在的持久物...