auto关键字

Posted Truman001

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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类型变量        
 7                                             存储在栈区,static类型变量存储在静态    
 8                                             区,二者不能同时使用,但在新语法中,
 9                                             auto已经不再作为存储类型指示符,
10                                             和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类    
14                                            型,但是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不能用于函数的参数
void foo (auto a ) //error
{
cout << typeid (a).name () << endl;
}
使用函数模板代替auto,如下:
template<typename T>
void foo (T a = T ())
{
cout << typeid (a).name () << endl;
}
(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不能用于数组元素
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("张飞");
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 }

 




以上是关于auto关键字的主要内容,如果未能解决你的问题,请参考以下文章

C 的“auto”关键字的目标

[ 深度解剖C语言 ] 关键字 ---- auto register

vs 2010代码片段

vs 2010代码片段

Alfred常见使用

深谈auto变量