免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
C++ 學(xué)習(xí)筆記(一些新特性總結(jié) 1)

雖然我也用了 C++ 有挺多年了,但是一直本著夠用就行的原則,沒有特別深入的學(xué)習(xí)過C++ 的語法,所以好多高級的 C++ 特性都不了解。正好最近從網(wǎng)上找到了本書《C++ 14 Quick Syntax Reference》,挺薄的一本書,只有 100多頁,但是覆蓋了基本所有 C++ 的特性。這個小短文就是我看這本書時摘抄下來的一些我以前沒有注意到的知識點。

文中所有代碼都在 gcc version 5.3.0 (Rev1, Built by MSYS2 project) 上測試通過。

16進制、8進制、2進制表示

int myOct = 062;int myHex = 0x32;int myBin = 0b00110010;
  • 1
  • 2
  • 3
  • 4

其中 16進制、8進制表示法是很早就支持的特性。2進制表示是 C++14 才正式支持的。
除此之外,C++14 還引入了單引號作為數(shù)字表示的分隔符。方便我們閱讀很長的數(shù)字。比如下面這個例子:

int longBin = 0b1010'0101'1010'0101;
  • 1
  • 2

加了三個單引號作為分割,讀起來就方便多了。

NULL 指針(nullptr)

早期的 C++ 中,我們用 0 或者 NULL 來表示無效的指針地址。C++11 專門引入了一個新的關(guān)鍵字 nullptr 來表示 NULL 指針。

int* p = nullptr; // ok
  • 1
  • 2

并且 nullptr 還是有類型的,類型為 nullptr_t:

nullptr_t mynull = nullptr; // ok
  • 1
  • 2

右值引用類型(C++11)

左值和右值都是針對表達式而言的,左值是指表達式結(jié)束后依然存在的持久對象,右值是指表達式結(jié)束時就不再存在的臨時對象。

所謂右值引用就是引用一個右值對象(臨時對象),比如下面的例子:

int&& ref = 1 + 2; // rvalue referenceref += 3;cout << ref; // "6"
  • 1
  • 2
  • 3
  • 4

ref 對應(yīng)的是 1+2的結(jié)果3,這是個臨時對象。傳統(tǒng)的C++引用方式是無法引用到這個臨時對象的。右值引用主要是解決效率問題,具體的方法可以搜索 “C++ 移動語義”。

原生字符串(raw string literals)

raw string 可以取消轉(zhuǎn)義字符的作用,是 C++11 中添加的新特性。比如:

string escaped = "c:\\Windows\\System32\\cmd.exe";
  • 1
  • 2

可以簡寫為:

string raw = R"(c:\Windows\System32\cmd.exe)";  
  • 1
  • 2

RAW String 開頭要用大寫的 R ,然后在雙引號內(nèi)要增加一對括號。

這個功能在其他的語言中早就有了。我們上邊這個例子還不大能看出 raw string 的優(yōu)勢,但是如果常寫正則表達式的話,就會感覺 raw string 太方便了。比如:

char str[] = R"(('(?:[^\\']|\\.)*'|"(?:[^\\"]|\\.)*")|)";
  • 1
  • 2

舊的寫法是:

char oldstr[] = "('(?:[^\\\\']|\\\\.)*'|\"(?:[^\\\\\"]|\\\\.)*\")|";
  • 1
  • 2

新的 char 類型

C++ 11 中引入了 char16_t 和 char32_t 兩種類型。這兩種字符類型可以分別用來存儲 utf-16 和 utf-32 編碼的字符。相應(yīng)的 string 類型也有兩個變種, u16string 和u32string。

string s3 = u8"UTF-8 string";u16string s4 = u"UTF-16 string";u32string s5 = U"UTF-32 string";
  • 1
  • 2
  • 3
  • 4

字符串前的 u8、u和 U也是新增的特性,分別用來支持 UTF-8、UTF-16和UTF-32 字符串。

for 循環(huán)

C++11 對 for 循環(huán)做了擴展,for 循環(huán)支持一種新的語法。

int a[3] = {1, 2, 3};for (int &i : a) {    cout <<i; // "123"}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

auto 和 decltype 關(guān)鍵字

這兩個關(guān)鍵字都是 C++ 11 中引入的。auto 關(guān)鍵字告訴編譯器自動推導(dǎo)變量的類型。比如下面的代碼:

auto i = 5; // intauto d = 3.14; // doubleauto b = false; // bool
  • 1
  • 2
  • 3
  • 4

如果我們希望推導(dǎo)出的類型是引用類型。那么需要在 auto 之后加個 &。比如下面這樣:

int& iRef = i;auto myAuto = iRef; // intauto& myRef = iRef; // int&
  • 1
  • 2
  • 3
  • 4

用 auto 之后可以簡化許多代碼。比如下面這個代碼:

vector<int> myVector { 1, 2, 3 };for(vector<int>::size_type i = 0; i != myVector.size(); i++) {    cout << myVector[i]; }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

用 auto 的話可以寫為:

for(auto i = 0; i != myVector.size(); i++) {    cout << myVector[i]; }
  • 1
  • 2
  • 3
  • 4
  • 5

當然,用上 for 的新語法,還可以寫的更簡便:

for (auto& x : myVector) {     cout << x << endl; } 
  • 1
  • 2
  • 3
  • 4
  • 5

decltype 與 auto 有些類似,它可以用來推導(dǎo)一個表達式的類型,比如下面的例子:

int a = 0b10'001'000;cout << a << endl;decltype(a) c = a + 1; //intcout << c << endl;decltype(3) b = 3; // int&&
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

需要解釋一下的是這個例子中 3 是個臨時變量。所以推導(dǎo)出 b 的類型是一個 int 型的右值引用。但是作為函數(shù)返回值時,推導(dǎo)出的就不是右值引用了。

decltype(5) getFive() { return 5; } // int
  • 1
  • 2

C++ 11 中 auto 和 decltype 還可以配合使用,用來推導(dǎo)函數(shù)的返回值類型。下面是個例子:

auto getValue(int x) -> decltype(x) { return x; } // int
  • 1
  • 2

這么寫還是挺繁瑣的, C++ 14 中做了簡化??梢院唵蔚膶憺椋?/p>

auto getValue(int x) { return x; } // int
  • 1
  • 2

不過我感覺這兩種函數(shù)寫法作用都不大,因為我們沒法在頭文件中把函數(shù)聲明寫為:

auto getValue(int x);
  • 1
  • 2

因為沒有函數(shù)體,根本無法做類型推導(dǎo)…

C++14 中還支持如下的寫法:

decltype(auto) = 3; // int&&decltype(auto) getRef(int& x) { return x; } // int&
  • 1
  • 2
  • 3

這些寫法知道也就行了,用處不大。

Lambda 函數(shù)

Lambda 函數(shù)的概念最早應(yīng)該來源于 Lisp 語言,現(xiàn)在也被 C++ 11 吸收進來了。
Lambda 函數(shù)使得我們可以像定義一個變量一樣定義一個函數(shù)。比如下面這樣:

auto sum = [](int x, int y) -> int {return x + y;};cout << sum(2, 3);
  • 1
  • 2
  • 3

上面的函數(shù)還可以簡寫為:

auto sum = [](int x, int y) { return x + y; };
  • 1
  • 2

編譯器會自動推導(dǎo)返回值的類型。

到了 C++ 14 Lambda 函數(shù)更是支持了泛型。

auto sum = [](auto x, auto y) {return x + y;};  cout << sum(2, 3) << endl;cout << sum(2.2, 3.0) << endl;cout << sum(2.2, 3) << endl;
  • 1
  • 2
  • 3
  • 4
  • 5

Lambda 函數(shù)也可以作為函數(shù)的參數(shù)傳遞給函數(shù)。下面是個例子:

#include <iostream>#include <functional>using namespace std;void call(int arg, function<void(int)> func) {    func(arg);}int main() {    auto printSquare = [](int x) { cout << x*x; };    call(2, printSquare); // "4"}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

上面的例子其實還說明 Lambda 函數(shù)不是普通的函數(shù)。它是一種特殊類型的對象。比如下面的 Lambda 函數(shù):

auto sum = [](int x, int y) {return x + y;};  
  • 1
  • 2

寫完整了應(yīng)該是 :

function<int(int)> sum = [](int x, int y) {return x + y;};  
  • 1
  • 2

Lambda 函數(shù)還有一些高級用法。比如Lambda 函數(shù)中的 “[]” 是有作用的。用它可以將所在域的其他變量引入到函數(shù)中。比如下面的例子:

void call(function<void()> func) { func(); }int main() {    int i = 2;    auto printSquare = [i]() { cout << i*i; };    call(printSquare); // "4"}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

Lambda 函數(shù)中 [] 里按值傳進去的參數(shù)是只讀的。所以下面的代碼是錯的:

int a = 10;int b = [a](int i) { a++; return a * i; } (5); // 50
  • 1
  • 2
  • 3

我們可以添加一個 mutable 關(guān)鍵字使得 a 不是只讀,但是 a 值的改變是不會影響函數(shù)外面的。

int a = 10;int b = [a](int i) mutable { a++; return a * i; } (5);cout << b << endl; // 55cout << a << endl; // 10
  • 1
  • 2
  • 3
  • 4
  • 5

Lambda 函數(shù)還可以是無名函數(shù),這時定義函數(shù)的同時也要調(diào)用這個函數(shù)。否則因為這個函數(shù)沒有名字,之后就沒有調(diào)用的機會了。下面這兩種寫法結(jié)果是相同的。

cout << [](int i) { return i*i; } (101) << endl;auto printSquare = [](int i) { return i*i; };cout << printSquare(101) << endl;
  • 1
  • 2
  • 3
  • 4
  • 5

利用 “[]” 也可以把結(jié)果傳出來。下面這兩種方法結(jié)果也是相同的。

int a = [](int i) { return i * i; } (11);cout << a << endl;[&a] (int i){ a = i * i;}(12);cout << a << endl;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

C++ 14 還支持一些新的特性,比如下面這樣:

int a = 1;[&, b = 2]() { a += b; }();cout << a; // "3"
  • 1
  • 2
  • 3
  • 4

關(guān)于 Lambda 函數(shù),知道這些也就差不多了。

第一篇先寫這么多。下一篇寫寫關(guān)于類和對象的一些新特性。

本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
30分鐘了解C++11新特性
C++ auto 關(guān)鍵字的使用
C 的 lambda 表達式,你總得知道一點兒
處理string對象中的字符c++primer 81
C++11/14的新特性
C++:C++11新特性詳解(1)
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服