C++11 新特性學習


在Linux下編譯C++11

#include<typeinfo>
int main()
{
    auto a=10;
    cout<<typeid(a).name()<<endl;    //得到a的類型,只是一個字符串
    return 0;   
}

編譯需要加-std=c++11,如下例:

0.98332977099667

auto

C++11中引入auto第一種作用是為了自動類型推導

auto的自動類型推導,用於從初始化表達式中推斷出變量的數據類型。通過auto的自動類型推導,可以大大簡化我們的編程工作

auto實際上實在編譯時對變量進行了類型推導,所以不會對程序的運行效率造成不良影響

另外,似乎auto並不會影響編譯速度,因為編譯時本來也要右側推導然后判斷與左側是否匹配。

auto a; // 錯誤,auto是通過初始化表達式進行類型推導,如果沒有初始化表達式,就無法確定a的類型  
auto i = 1; 
auto d = 1.0; 
auto str = "Hello World"; 
auto ch = 'A'; 
auto func = less<int>(); 
vector<int> iv; 
auto ite = iv.begin(); 
auto p = new foo() // 對自定義類型進行類型推導

auto不光有以上的應用,它在模板中也是大顯身手,比如下例這個加工產品的例子中,如果不使用auto就必須聲明Product這一模板參數:

template <typename Product, typename Creator>  
void processProduct(const Creator& creator) { 
    Product* val = creator.makeObject(); 
    // do somthing with val 
}
如果使用auto,則可以這樣寫:
template <typename Creator> 
void processProduct(const Creator& creator) {  
    auto val = creator.makeObject(); 
    // do somthing with val 
}

拋棄了麻煩的模板參數,整個代碼變得更加正解了。

decltype

decltype實際上有點像auto的反函數,auto可以讓你聲明一個變量,而decltype則可以從一個變量或表達式中得到類型,有實例如下:

int x = 3;  
decltype(x) y = x;
有人會問,decltype的實用之處在哪里呢,我們接着上邊的例子繼續說下去,如果上文中的加工產品的例子中我們想把產品作為返回值該怎么辦呢?我們可以這樣寫:
template <typename Creator>  
auto processProduct(const Creator& creator) -> decltype(creator.makeObject()) {  
    auto val = creator.makeObject();  
    // do somthing with val  
}

typeid().name()與decltype

typeid().name得到的僅僅是一個字符串

而decltype可以提取出類型

nullptr

nullptr是為了解決原來C++中NULL的二義性問題而引進的一種新的類型,因為NULL實際上代表的是0

void F(int a){  
    cout<<a<<endl;  
}  
 
void F(int *p){  
    assert(p != NULL);  
 
    cout<< p <<endl;  
}  
 
int main(){  
 
    int *p = nullptr;  
    int *q = NULL;  
    bool equal = ( p == q ); // equal的值為true,說明p和q都是空指針  
    int a = nullptr; // 編譯失敗,nullptr不能轉型為int  
    F(0); // 在C++98中編譯失敗,有二義性;在C++11中調用F(int)  
    F(nullptr);  
 
    return 0;  
}

序列for循環

在C++中for循環可以使用類似java的簡化的for循環,可以用於遍歷數組,容器,string以及由begin和end函數定義的序列(即有Iterator),示例代碼如下:

map<string, int> m{{"a", 1}, {"b", 2}, {"c", 3}};  
for (auto p : m){  
    cout<<p.first<<" : "<<p.second<<endl;  
}

更加優雅的初始化

在引入C++11之前,只有數組能使用初始化列表,其他容器想要使用初始化列表,只能用以下方法:

int arr[3] = {1, 2, 3};
vector<int> v(arr, arr + 3);

在C++11中,我們可以使用以下語法來進行替換:

int arr[3]{1, 2, 3};
vector<int> iv{1, 2, 3};
map<int, string>{{1, "a"}, {2, "b"}};
string str{"Hello World"};

alignof和alignas 

C++11標准中,為了支持對齊,引入了兩個關鍵字:操作符alignof和對齊描述符alignas。

操作符alignof:用於返回類的對齊方式,即對齊值

對齊描述符alignas:用於設置類使用哪種對齊方式

struct alignas(32) A
{
    char a;
    int b;
};
 
int main()
{
    //由於用alignas設置了對齊方式,原本大小為8字節的類A變為32字節了
    cout << sizeof(A) << endl;       //輸出:32
    cout << alignof(A) << endl;      //輸出:32
 
    //alignas既可以接受常量表達式,也可以接受類型作為參數
    alignas(8) int a;
    alignas(alignof(double)) int b;
}

  C++11標准中規定了一個“基本對齊值”。一般情況下其值等於平台上支持的最大標量類型數據的對齊值。我們可以通過alignof(std::max_align_t)來查詢其值。而像之前我們把對齊值設置為32位的做法稱為擴展對齊,這按照C++標准該程序是不規范的,可能會導致未知的編譯錯誤或者運行時錯誤。

  其余對齊方式有STL庫函數(std::align),還有STL庫模板類型(aligned_storage和aligned_union)。

Lambda表達式

見另一篇:https://www.cnblogs.com/WindSun/p/11182276.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM