在Linux下編譯C++11
#include<typeinfo> int main() { auto a=10; cout<<typeid(a).name()<<endl; //得到a的類型,只是一個字符串 return 0; }
編譯需要加-std=c++11,如下例:
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 }
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;
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)。