在C++11新標准中,語言本身和標准庫都增加了很多新內容,本文只涉及了一些皮毛。不過我相信這些新特性當中有一些,應該成為所有C++開發者的 常規裝備。你也許看到過許多類似介紹各種C++11特性的文章。下面是我總結的,C++開發者都需要學習和使用的C++11新特性。
auto
在C++11之前,auto關鍵字用來指定存儲期。在新標准中,它的功能變為類型推斷。auto現在成了一個類型的占位符,通知編譯器去根據初始化 代碼推斷所聲明變量的真實類型。各種作用域內聲明變量都可以用到它。例如,名空間中,程序塊中,或是for循環的初始化語句中。
- auto i = 42; // i is an int
- auto l = 42LL; // l is an long long
- auto p = new foo(); // p is a foo*
使用auto通常意味著更短的代碼除非你所用類型是int,它會比auto少一個字母)。試想一下當你遍歷STL容器時需要聲明的那些迭代器iterator)。現在不需要去聲明那些typedef就可以得到簡潔的代碼了。
- std::map<std::string, std::vector<int>> map;
- for(auto it = begin(map); it != end(map); ++it)
- {
- }
需要注意的是,auto不能用來聲明函數的返回值。但如果函數有一個尾隨的返回類型時,auto是可以出現在函數聲明中返回值位置。這種情況下,auto 並不是告訴編譯器去推斷返回類型,而是指引編譯器去函數的末端尋找返回值類型。在下面這個例子中,函數的返回值類型就是operator+操作符作用在 T1、T2類型變量上的返回值類型。
- template <typename T1, typename T2>
- auto compose(T1 t1, T2 t2) -> decltype(t1 + t2)
- {
- return t1+t2;
- }
- auto v = compose(2, 3.14); // v's type is double
nullptr
以前都是用0來表示空指針的,但由於0可以被隱式類型轉換為整形,這就會存在一些問題。關鍵字nullptr是std::nullptr_t類型的 值,用來指代空指針。nullptr和任何指針類型以及類成員指針類型的空值之間可以發生隱式類型轉換,同樣也可以隱式轉換為bool型取值為 false)。但是不存在到整形的隱式類型轉換。
- void foo(int* p) {}
- void bar(std::shared_ptr<int> p) {}
- int* p1 = NULL;
- int* p2 = nullptr;
- if(p1 == p2)
- {
- }
- foo(nullptr);
- bar(nullptr);
- bool f = nullptr;
- int i = nullptr; // error: A native nullptr can only be converted to bool or, using reinterpret_cast, to an integral type
為了向前兼容,0仍然是個合法的空指針值。
Range-based for loops 基於范圍的for循環)
為了在遍歷容器時支持”foreach”用法,C++11擴展了for語句的語法。用這個新的寫法,可以遍歷C類型的數組、初始化列表以及任何重載了非成員的begin()和end()函數的類型。
如果你只是想對集合或數組的每個元素做一些操作,而不關心下標、迭代器位置或者元素個數,那麼這種foreach的for循環將會非常有用。
- std::map<std::string, std::vector<int>> map;
- std::vector<int> v;
- v.push_back(1);
- v.push_back(2);
- v.push_back(3);
- map["one"] = v;
- for(const auto& kvp : map)
- {
- std::cout << kvp.first << std::endl;
- for(auto v : kvp.second)
- {
- std::cout << v << std::endl;
- }
- }
- int arr[] = {1,2,3,4,5};
- for(int& e : arr)
- {
- e = e*e;
- }
- C++ 11 CPP 11 features