当前位置: 首页 > news >正文

C++ auto关键字

auto关键字:

一、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 }    

参考:C语言中的4中存储类型

二、C++11标准中auto关键字不再表示变量的存储类型,而是用于自动推导表达式或变量的实际类型的

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   
17     auto d=4.38;      //double
18     auto s("hello");  //const char*
19     auto z = new auto(10); // int*
20     auto x1 = 5, x2 = 5.0, x3='c';//错误,必须是初始化为同一类型
}                

使用C++11的auto定义变量时必须对其进行初始化,在编译阶段编译器需要根据初始化表达式来推导auto的实际类型。因此auto并非是一种"类型"的声明,而是一个类型声明时的"占位符”,编译器在编译期会将auto替换为变量实际的类型。
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 }

3、auto使用的限制
(1)auto不能用于函数的参数

 1 void foo (auto a )    //error2 {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)类的非静态数据成员不能包含auto类型

class A
{
public:int m_x = 0;//类的非静态数据成员不能包含auto类型auto m_y = 1;//errorstatic auto const m_z = 2;
};

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

(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]
}

4、何时使用auto
(1)通过auto减少模板的类型参数

 1 class A2 {3 public:4   A(int arg = 0) :m_var(arg){}5   int get(void)const6   {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)通过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 }
http://www.wxhsa.cn/company.asp?id=2078

相关文章:

  • API 响应体加密场景下的调试实践:Postman 的局限与 Apipost 的优化
  • ARM主板:低功耗高性能的嵌入式计算核心
  • Gin 模板系统深度解析:客服系统实战开发
  • 系统盘爆了,.vscode,.android占内存太多,使用mklink命令符号链接
  • Acrobat Pro DC 2025下载及破解安装教程,附永久免费免激活中文破解版Acrobat Pro DC安装包(稳定版)
  • java锁升级过程
  • GAS_Aura-Setting Up Click to Move
  • 2025绩效管理必知
  • 【刷题笔记】cf808f
  • Laravel APP_DEBUG=true:存在账户信息泄露风险
  • 将当前目录下的所有文件 / 目录完整复制到/tmp目录,且会保留文件的权限、所有者、时间戳等属性
  • C# 操作 DXF 文件指南
  • 在Proxmox中部署Security Onion的安全配置实战
  • 报表到 BI:企业数据从展示到决策的进阶之路
  • 抢先体验智能测试时代,QA必备AI测试工具
  • Flink 与Flink可视化平台StreamPark教程(DataStreamApi基本使用)
  • 内部排序-直接插入排序
  • 玩转n8n测试自动化:核心节点详解与测试实战指南
  • Linux:龙晰系统(Anolis)更新yum(dnf)仓库源
  • (笔记)多项式基础 FFT
  • MAC tomcat启动报错
  • 研究生-必看-倒计时3天/武汉科技大学主办/稳定EI会议/高层次教授出席报告
  • LGP7113 [NOIP 2020] 排水系统 学习笔记
  • MySqlException: Incorrect string value: \xE6\x99\xBA\xE8\x83\xBD... for column FieldName at row 1
  • Burp Suite Professional 2025.9 发布 - Web 应用安全、测试和扫描
  • SQL Server 2022 RTM 累积更新 #21 发布
  • 针对WPF的功耗优化(节能编程)
  • Docker 清理完整指南:释放磁盘空间的最佳实践 - 详解
  • 微算法科技(NASDAQ: MLGO)开发Rollup技术,探索区块链扩展性解决方案
  • 征稿倒计时3天/武汉科技大学主办/医学人工智能/现可享优惠