• 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 }




  • 相关阅读:
    C#将一个字符串数组的元素的顺序进行反转
    C#找出100内所有的素数/质数
    C#流程控制for循环语句,水仙花数。
    C# 常用的操作文件夹的方法
    Element UI
    JS
    JS
    PHP基础算法
    js实现csv下载
    el-dialog“闪动”解决办法
  • 原文地址:https://www.cnblogs.com/LuckCoder/p/8467617.html
Copyright © 2020-2023  润新知