[學習筆記] 記一些 C++, C++11 的語法
\(\cal{C}\)\(\text{++}\)
函式的預設引數
預設引數除了使用數值常量指定,也可以使用表示式指定:
int Value=233; void TellTheTruth(int ET,int make,int shit=Value) { cout<<ET<<make<<shit; }
需要注意的是,預設引數只能放在形參列表的最後,而且一旦為某個形參指定了預設值,那麼它後面的所有形參都必須有預設值。
\(\cal{C}\)\(\text{++11}\)
新的空指標 —— \(\text{nullptr}\)
因為 \(\text{NULL}\) 也可以相當於 \(0\),所以可以避免一些錯誤。
\(\text{constexpr}\)
使用 \(\text{constexpr}\) 定義常量,可以幫助你檢查是否為常量表達式,就像這樣:
int a;
constexpr int b=a+233;
此時就會報錯。
\(\text{auto}\)
\(\text{auto}\) 可以在一條語句宣告多個變數,但它們的資料型別必須相同。
其次,\(\text{auto}\) 一般會忽略引用:
int a=0,&b=a;
auto c=b;
此時的 \(c\) 是一個整型,其值為 \(0\)。對它的修改和 \(a,b\) 沒有半毛錢關係。
\(\text{decltype}\)
使用 \(\text{decltype}\) 可以從表示式中推斷出要定義變數的型別,且不用表示式的值去初始化變數。比如:
int a=0;
decltype(a) b; // b 的型別為整型
不過,\(\text{decltype}\) 只會用表示式的返回值進行推斷,並不會執行表示式。又比如:
int function() { cout<<"xyyzka!"<<endl; return 233; } decltype(function()) a;
此時 function()
並不會被真正執行。
另外,\(\text{decltype}\) 還可以處理一個 \(\text{auto}\) 的問題 —— 無法得到引用型別。就像這樣:
int a=0,&b=a;
decltype(b) c;
此時 \(c\) 的型別為 int&
。
另外,如果加上 ()
,就可以得到此資料型別的引用:
int a;
decltype((a)) b; // b 的型別為 int&
尾置返回型別
比如返回一個二維陣列:
auto function(int x) -> int(*)[10][10] {
// Do something...
}
這個可以配合 \(\text{decltype}\) 食用:
auto function(int x) -> decltype(x) {
// Do something...
}
\(\text{Lambda}\) 表示式
基本構成:
[capture list] (params list) mutable exception -> return type { function body }
- \(\text{capture list}\):捕獲外部變數列表。不可以省略。
- \(\text{params list}\):形參列表。不可以省略。
- \(\text{mutable}\) 指示符:用來說用是否可以修改捕獲的變數。可以省略。
- \(\text{return type}\):返回型別。編譯器可以根據 \(\text{return}\) 語句推斷返回型別,但需要注意同時 \(\text{return}\) 兩種型別就會報錯,可以省略。
- \(\text{function body}\):函式體。不可以省略。
一般可用於簡化排序:
vector <int> vec;
sort(vec.begin(),vec.end(),[](int a,int b) {
return a>b;
});
值捕獲
被捕獲變數的值在 \(\text{Lambda}\) 表示式建立時 通過值拷貝的方式傳入,隨後對該變數的修改不會影響到 \(\text{Lambda}\) 表示式內部的值。
int a=1,b=2,c=3;
auto function = [a]() { /* Do something */ };
這時就可以在函式內部使用 \(a\) 了。
如果想要使用所有的區域性變數呢?
int a=1,b=2,c=3;
auto function = [=]() { /* Do something */ };
另外,如果實在想在函式內修改值,可以加上 \(\text{mutable}\):
int a=1,b=2,c=3;
auto function = [=]() mutable { /* Do something */ };
但此時對變數的修改也不會影響到函式之外。
引用捕獲
在前面加上 &
即可,如果想要使用所有的區域性變數,也可以這樣寫:
int a=1,b=2,c=3;
auto function = [&]() { /* Do something */ };
混合捕獲
比如這個:
int a=1,b=2,c=3;
auto function = [&,a]() { /* Do something */ };
\(a\) 是值捕獲,其餘變數是引用捕獲。一些組合也類似,就不講了。