C++auto關鍵字


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 }

 

 





免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM