->auto
自動類型推斷,編譯器可以根據(jù)表達式的類型,自動決定變量的類型,C++14開始,還可以自動推斷函數(shù)的返回類型,不需要手工聲明。auto的變量類型仍然是編譯時就確定了的(C++是靜態(tài)類型語言),只不過編譯器能夠自動填充這個類型。
->decltype
獲得一個表達式的類型,結(jié)果可以跟類型一樣使用。
decltype(變量名)獲取變量的精確類型
decltype(表達式)獲取表達式的引用類型,如果表達式的結(jié)果是prvalue的情況獲得值類型
int a;
decltype(a) // int
decltype((a)) // int& -> a是lvalue
decltype(a+a) // int -> a+a是prvalue
->decltype(auto)
用auto定義變量時需要確定時值類型還是引用類型。auto auto& auto&&
decltype(expr)既可以時值類型也可以是引用類型,因此可以寫decltype(expr) a = expr;
C++14引入了decltype(auto) a = expr;當expr很長的時候可以很好的簡化書寫
這種代碼主要用于通用的轉(zhuǎn)發(fā)函數(shù)模板中:不知道調(diào)用的函數(shù)是不是會返回一個引用。
->C++14函數(shù)的返回值可以用auto decltype(auto)聲明。還引入了后置返回值類型聲明。
auto foo(para) -> returntype {}
類模板的模板參數(shù)推導(dǎo)
auto pr = make_pari(1, 11);
C++17: pair pr{1, 11};
array<int,3> arr{1,2,3};
C++17: array arr{1,2,3}
列表初始化
容器的初始化列表可以以更簡單的方式初始化對象。vector<int> v{1,2,3}
這不僅僅是針對標準容器的特殊方法,而是一個通用的,可以用于各種類型的方法。
編譯器對{1,2,3}這樣的表達式自動生成一個初始化列表initializer_list<int>,代碼只需要聲明一個接收initializer_list的構(gòu)造函數(shù)即可使用。效率方面,對于動態(tài)對象容器和數(shù)組都是通過拷貝構(gòu)造進行初始化。
統(tǒng)一初始化 uniform initialization
C++11引入了統(tǒng)一初始化的新語法,用{}來進行對象的初始化,{}初始化優(yōu)先匹配initializer_list。
統(tǒng)一初始化避免了the most vexing parse
T1 name1(T2(name2)); // C++標準將其視為函數(shù)聲明T1 name(T2 name2),而不是a function style cast
conversion operator:
用于將一個類型的對象轉(zhuǎn)換成另一個類型的對象operator T() {} 可以看作是對()的重載。當需要一個T類型的變量時,operator T() 將會被調(diào)用
T a = obj; <=> T a = (T)obj;
converting constructor:
調(diào)用時只需要傳入一個實參的構(gòu)造函數(shù),相當于一個隱式類型轉(zhuǎn)換的方法。不過類類型轉(zhuǎn)換只允許一步轉(zhuǎn)換。如果要禁止這種隱式類型轉(zhuǎn)換可以將構(gòu)造函數(shù)聲明為explicit
class test
{
? ? test(string s) {}
? ? void add(const test& t) {}
}
string s = "hello";
test t("hello");
t.add(s); // OK s隱式類型轉(zhuǎn)換為test類型
t.add("hello"); // NG hello->string->test兩步轉(zhuǎn)換
C++11類數(shù)據(jù)成員的默認初始化
class XX
{
private:
? ? m_f1{0}; // 如果構(gòu)造函數(shù)沒有提供初始化列表,則成員初始化由默認初始化完成
}