auto關鍵字:
1.C++98標准auto關鍵字的作用和C語言的相同,表示自動變量,是關於變量存儲位置的類型飾詞,通常不寫,因為局部變量的默認存儲就是auto
1 void foo(void) 2 { 3 int a; //變量存儲在棧區 4 auto int b; //自動變量,存儲在棧區 5 static int c; //靜態變量,存儲在數據區 6 register int d; //寄存器變量,存儲在寄存器中 7 }
2.C++11標准中auto關鍵字不再表示變量的存儲類型,而是用於類型推導
(2.1)auto的基本用法
1 void foo(void) 2 { 3 auto a = 1; //a是int類型 4 auto b = new auto(2); //b是int *類型 5 auto const *c = &a; //c是const int *類型 6 static auto d = 4.0; //d是double類型,在舊語法中,auto類型變量存儲在棧區,static類型變量存儲在靜態區,二者不能同時使用,但在新語法中,auto已經不再作為存儲類型指示符,和static關鍵字沒有沖突,可以合用 11 auto e; //error,C++11標准中auto變量必須被初始化 12 auto const *f = &a,g = 4.0; //error,類型推導不能帶有二義性 13 auto const *h = &a,i; //error,雖然可以根據&a得出auto表示int類型,但是i依然需要顯示初始化 15 auto int j = 3; //error,auto不能與其他任何類型說明符組合使用 16 }
(2.2)auto和指針或者引用結合使用
1 void foo(void) 2 { 3 int a = 0; 4 auto *b = &a; //b是int *類型 5 auto c = &a; //c是int *類型 6 auto &d = a; //d是int&類型 7 cout << &d << ' ' << &a << endl; //地址相同 8 auto e = d; //e是int類型,當表達式帶有引用屬性時,auto會拋棄其引用屬性,直接推導為原始類型 9 cout << &e << ' ' << &a << endl; //地址不同 10 auto const f = a; //f是int const 類型 11 cout<<++f<<endl; //error,f帶有常屬性 12 auto g = f; 13 cout<<++g<<endl; //g的值為1,當表達式帶有CV限定時,auto會拋棄其CV限定 14 auto const &h = a; 15 auto &i = h; //i是int const &類型 16 cout<<++i<<endl; //error,如果auto和引用或者指針結合使用,表達式的CV限定會被保留下來 17 auto *j = &h; //j是int const *類型 18 cout<<++*j<<endl; //error,如果auto和引用或者指針結合使用,表達式的CV限定會被保留下來 19 }
(2.3)auto使用的限制
(2.3.1)auto不能用於函數的參數
1 void foo (auto a ) //error 2 { 3 cout << typeid (a).name () << endl; 4 } 5 //使用函數模板代替auto,如下: 6 template<typename T> 7 void foo (T a = T ()) 8 { 9 cout << typeid (a).name () << endl; 10 }
(2.3.2)類的非靜態數據成員不能包含auto類型
class A { public: int m_x = 0; //類的非靜態數據成員不能包含auto類型 auto m_y = 1;//error static auto const m_z = 2; };
(2.3.3)auto不能用於模板的類型實參
1 template<typename T> 2 class B 3 { 4 public: 5 B (T const& arg) : m_var (arg) {} 6 T m_var; 7 }; 8 void main() 9 { 10 B<int> b1(0); //true 11 B<auto> b2 = b1; //error,auto不能用於模板的類型實參 12 }
(2.3.4)auto不能用於數組元素
void func() { int arr1[10]; auto arr2[10] = arr1; //error,auto不能用於數組元素 auto arr3 = arr1; //true,arr3是int *類型,arr1代表數組首地址 auto &arr4 = arr1; //true,arr4是int(&)[10]類型,arr1代表數組整體 cout << typeid (arr4).name () << endl;//int[10] }
(2.4)何時使用auto
(2.4.1)通過auto減少模板的類型參數
1 class A 2 { 3 public: 4 A(int arg = 0) :m_var(arg){} 5 int get(void)const 6 { 7 return m_var; 8 } 9 void set(int arg) 10 { 11 m_var = arg; 12 } 13 private: 14 int m_var; 15 }; 16 17 class B 18 { 19 public: 20 B(const char *arg):m_var(arg){} 21 const char *get(void)const 22 { 23 return m_var; 24 } 25 void set(const char *arg) 26 { 27 m_var = arg; 28 } 29 private: 30 const char *m_var; 31 }; 32 33 //template <typename V,typename X> 34 template <typename X> 35 void foo(X const &x) 36 { 37 //V var = x.get(); 38 auto var = x.get(); 39 cout << typeid(var).name() << endl; 40 } 41 42 void main(void) 43 { 44 A a(1234); 45 //foo<int> (a); 46 foo(a);// 通過auto減少模板的類型參數 47 48 B b("abcd"); 49 foo(b); 50 }
(2.4.2)通過auto簡化復雜類型的書寫
1 void foo(void) 2 { 3 multimap<string, int> msi; 4 msi.insert(make_pair("張飛", 100)); 5 msi.insert(make_pair("趙雲", 90)); 6 msi.insert(make_pair("關羽", 80)); 7 msi.insert(make_pair("張飛", 95)); 8 msi.insert(make_pair("趙雲", 85)); 9 msi.insert(make_pair("關羽", 75)); 10 pair<multimap<string, int>::iterator, multimap<string, int>::iterator> range1 = msi.equal_range("張飛");//equal_range()函數查找multimap中鍵值等於key的所有元素,返回指示范圍的兩個迭代器。 11 int sum1 = 0; 12 for (multimap<string, int>::iterator it = range1.first; it != range1.second;++it) 13 { 14 sum1 += it->second; 15 } 16 cout << sum1 << endl; 17 18 auto range2 = msi.equal_range("張飛"); 19 int sum2 = 0; 20 for (auto it = range2.first; it != range2.second; ++it) 21 { 22 sum2 += it->second; 23 } 24 cout << sum2 << endl; 25 }