目錄
Uniform Initialization (一致性初始化)
explicit for ctors taking more than one argument
ranged-based for statement --for循環
variadic-templates可變模版參數
語法:typename…,這三個點已經成爲了語言的一部分。
example:
void print()
{
}
template<typename T, typename... Types>
void print(const T& firstArg, const Type&... args)
{
cout<<firstArg<<endl;
print(args...);
}
print(7.5, "hello", bitset<16>(377), 42);
hashtable:根據函數輸入參數不同調用1/2/3/4不同方法,具體如下圖所示:
tuple
tuple<int, float,string>:允許你放任意東西,這個是你自己指定,變成一個對象。如下圖所示:
Space in Template Expressions
模版表達式的空格:模版參數本身也是一個模版,有兩個空格。
vector<list<int> > 在每個版本都適用
vector<list<int>> c++11後可以
nullptr and std::nullptr_t
// C++11之後指針可以用 nullptr代替 0 or NULL
void f(int);
void f(void*);
f(0); // call f(int)
f(NULL); // call f(int) if NULL is 0 ambiguous
f(nullptr); // call f(void*)
auto
概念:不用管一個對象的類型,編譯器會自己去推理其類型
// #1 c++11 you can declare a var or an object without specifiying type by using auto
auto i = 42;
double f();
auto d = f();
// #2 auto用於2種情況 第一種是type太長 另一種是複雜的表達式 lambda
vector<int> v;
// vector<int>::iterator pos;
// pos = v.begin();
auto pos = v.begin();
auto l = [](int x) -> bool{}//沒有名稱的函數
example:
list<string> c;
...
list<string>::iterator ite;
ite = find(c.begin(), c.end(), target);
//爲了方便,可以用auto
list<string> c;
...
auto ite = find(c.begin(), c.end(), target);//正確寫法
auto ite; //錯誤寫法
ite = find(c.begin(), c.end(), target);
//如果每次聲明的時候都賦值時,所有的變量都用auto是可以的,但不推薦初學者這樣使用。
Uniform Initialization (一致性初始化)
原理: 編譯器看到大括號 {t1,t2,tn}變做出一個 Initializer_list 他關聯到一個array<T,n> 調用ctor的時候 array內的元素被編譯器被逐一賦值給ctor。但如果參數參數是個Initializer_list 那就將參數打包直接發給函數。
// 如何初始化一個對象或變量,c++11 之前 新手很容易困惑 初始化可能發生在() {} =操作符
// c++11 後統一一個方法 用{}
int a[] = {1,2,3,4};
vector<int> v{2,3,4,5,6};
vector<string> city {
"New York", "London", "Beijing"
};
comlex<int> c{4.0, 3.0}; // 等價於 c(4.0, 3.0);
// c++ 11 之前
Rect r1 = {3,7,&area};
Rect r1(3,7,&area);
Initializer Lists
爲了完成一致性設初值,大括號背後是做出一個 Initializer_list,個數可變的元素。
1、大括號可以用來設初值。
int i; // i沒有定義初值
int j{}; // j定義初值爲0
int* p; // 指針p沒有初值
int *q{}; // 指針q的初值是nullptr
2、大括號裏的元素類型必須一致
從一致性設初值的方式,瞭解到了{}的作用,下面瞭解以下 Initializer_list的原理。比如下圖例子:
print(定義的容器必須是int類型)。定一個class P類,定義構造函數,測試用例:
#include <iostream>
// #include <initializer_list>
using namespace std;
// 支持函數接受任意個數的參數
// vector<int> v{1,2,3,4,5,6};
// 的實現原理就是將{1,2,3,4,5}包裝成initializer_list 調用參數是initializer_list的ctor
void print(initializer_list<int> vals) {
for (auto p = vals.begin(); p!=vals.end(); ++p) {
cout << *p << ' ';
}
cout << endl;
}
class P{
public:
P(int a, int b){
cout << "P(int a,int b)=" <<a << ' ' << b << endl;
};
P(initializer_list<int> initlist) {
cout << "P(initializer_list<int>)=";
for(auto i : initlist) {
cout << i << ' ';
}
cout << endl;
}
};
int main() {
print({1,2,3,4,5,6,7});
P p(77,5);
P q{77,5};
P r{77,5,23};
// 調用構造函數
P s = {77, 5};
}
max/min只能接受兩個參數來對比。
array
換個形式的數組。具體的可以看看我寫的STL源碼剖析:https://blog.csdn.net/qq_27262727/article/details/105248954
explicit for ctors taking more than one argument
概念:explicit用來針對構造函數接受一個以上實參。
explicit(明白的,明確的)接收單一實參example:
下圖左邊是允許的,下圖右邊加入explicit之後,不允許要編譯器做轉換,必須輸入跟定義的一致才行,否則會報錯。
一個以上輸入實參example:
//!表示加入explicit,報錯的
ranged-based for statement --for循環
for的新形式:使用:來遍歷動作。
//例子1
for(decl : coll) {
statement
}
// 等價於下面
for(auto pos = coll.begin(), end=coll.end(); pos!=end; ++pos) {
decl = *pos
statment
}
//例子2
for(int i : {1,2,3,4,5,1,3}) {
std::cout << i << ' ';
}
for(auto e : v) {
std::cout << e << " ";
}
for(auto& e: v) {
e *= 3;//加入引用,拿出來的東西e會根據操作改變原來元素內容,影響原來的元素,而且引用的話速度會變得很快。
std::cout << e << " ";
}
for循環內部做的事情: