C++11新特性
範圍for
迴圈
std::vector<int> nums;
for (auto it : nums){
cout << *it << endl;
}
array<5, int> a{1, 2, 3 ,4 ,5};
for (auto x : a){
x *= 2; // 此時a中元素不會發生改變a{1, 2, 3, 4, 4}
}
for (auto& x : a){
x *= 2; // 此時a中元素會發生改變a{2, 4, 6, 8, 8}
}
for_each(a.begin(), a.end(), [](int x){x*=2;}) // a中元素不會發生改變
移動語義特殊成員函式
參見st::move()
實現移動建構函式和移動賦值運算子
轉換構造器
轉換構造器支援花括號列表語義到引數的轉換
class MyClass{
pulic:
MyClass(int){}
MyClass(int, int){}
};
MyClass b{1,2};
顯式轉換函式
explict
可用於類構造器和運算子中禁止隱式轉換,比如禁止基礎資料型別直接隱式轉換為類物件。
class MyClass{
explict MyClass(int){
/* code */
}
};
void Func(MyClass a){
}
MyClass a(1.1); // OK, 只是float->int的隱式轉換,不涉及到類物件的轉換,此時是可行的。
Func(1.1); // Error, 此時會涉及float->MyClass的隱式轉換,但是由於explict宣告會拒絕隱式型別轉換
Func(MyClass(1.1)); // OK, 顯示指明轉換型別
內聯名稱空間
內聯空間可以使該空間像是父空間的一部分。
namespace Parent{
namespace Cousin{
void GetCousinName(){}
}
inline namespace Son{
void GetSonName(){}
}
}
Parent::Cousin::GetCousinName(); // 巢狀的名稱空間的作用域在巢狀作用域中,也是侄子有私人空間
Parent::GetSonName(); // 內聯名稱空間作用域在父空間中,兒子沒有私人空間。
using Parent::Cousin::GetCousinName; // 匯入名稱空間中的函式
GetCousinName();
namespace cousin = Parent::Cousin; //名稱空間別名
非靜態資料成員初始化
C++11允許非靜態成員初始化。
class Cat{
Cat(int a) : val(a){}
int val = 0; // 允許非靜態成員直接初始化
int name {0};
};
右角括號
map<map<int, int>>; // C++11才支援可以無空格連續右角括號
引用限定成員函式
引用限定成員函式能夠檢查物件的*this
是一個左值引用還是右值引用
class Cat{
public:
Cat(int a) : val(a){}
void GetName() &{
cout << "lvalue" << endl;
}
void GetName() &&{
cout << "rvalue" << endl;
}
private:
int val = 0; // 允許非靜態成員直接初始化
int name {10};
};
int main()
{
Cat s(5);
s.GetName(); // 左值呼叫GetName() &
move(s).GetName(); // 右值引用呼叫GetName() &&
Cat&& m = move(s);
m.GetName(); // lvalue,此時就會出現右值傳入時會退化為左值
}
尾部返回型別
允許使用->
來為lambda
和不明確函式返回型別指定返回型別。
auto Func1() -> int{
/* code */
}
auto Func2 = []() -> int{};
noexcept
限定符
noexcept
關鍵字告訴編譯器該函式不會丟擲任何異常,從而允許編譯器最佳化。如果丟擲了異常,會用std::terminate
終止程式執行。可以省略一些編譯器生成一些異常處理程式碼。可以是條件性判斷丟擲異常。noexcept
常用於修飾需要更改資源訪問的函式,比如預設建構函式、解構函式、移動建構函式、移動賦值運算子、複製建構函式、複製賦值運算子。
void Add(int a, int b) noexcept{
// 不會丟擲任何異常
}
void AddIf(int a, int b) noexcept(false){
// 可能會丟擲異常
}
char32_t
和char16_t
標準型別
char32_t
char16_t
代表UTF-8
字串(1-4個位元組)
原始字面字串
舉例完成對原生字面字串語法的展現
const char* str = "hello,\nworld\n";
// 等價於
const char* str = R"(hello,
world)";