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 }