auto声明自动变量,在栈上,自动分配自动回收,但是在CPP中不能这样用
总结:CPP中,auto是一种自适应类型,它会根据初始化的变量而自动推导类型,不能和int,double等关键字相结合。
auto 让编译器通过初始值来进行类型推演。从而获得定义变量的类型,所以说 auto 定义的变量必须有初始值。
应用场景
当变量类型名很长时使用auto自动推导类型用auto当变量类型不确定时用auto(2)返回值占位
#include <iostream> using namespace std; template <typename T1, typename T2> auto compose(T1 t1, T2 t2) { return t1 + t2; } void main() { cout << compose(1, 11.1) << endl;//错误 cin.get(); }#include <iostream> using namespace std; template <typename T1, typename T2> auto compose(T1 t1, T2 t2) -> decltype(t1 + t2) { return t1 + t2; } void main() { cout << compose(1, 11.1) << endl;//错误 cin.get(); }
总结:
函数模板中,与decltype结合表示函数返回的类型decltype操作符用于查询表达式的数据类型。auto在这里的作用也称为返回值占位,它只是为函数返回值占了一个位置,真正的返回值是后面的decltype(t1 + t2)当模板函数的返回值依赖于模板的参数时,我们依旧无法在编译代码前确定模板参数的类型,故也无从知道返回值的类型,这时我们可以使用auto。
正确的代码应该是:
#include <iostream> using namespace std; int main() { int* pp = new auto(1); auto x = new auto(11.1); auto* y = new auto(9); cin.get(); }总结:auto变量必须初始化,以便从初始化表达式中推导出变量类型。对比const
使用auto可以在一个语句中声明多个变量,但是因为一个声明中只能有一种基本数据类型,所以该语句中私有变量的初始基本类型必须是一样的。
注意区分数据类型和类型修饰符:
#include <iostream> using namespace std; void main() { int i(3);; //()仅用于初始化 auto a = i, &b = i, *c = &i;//正确: a初始化为i的副本,b初始化为i的引用,c为i的指针. auto i1=0,*p=&i1; //正确,i1是整数,p是指向i1的指针 cin.get(); }
auto会忽略引用
#include <iostream> using namespace std; void main() { int a{ 10 }; cout << typeid(a).name() << endl; //int int &b = a; //将a的值取出来放入b b = 11; cout << typeid(b).name() << endl; //int //b是一个引用,去除引用 int &d = b; d = 12; cout << typeid(d).name() << endl; //int auto c = b; c = 12; cout << typeid(c).name() << endl; //int auto &e = b; e = 13; cout << typeid(e).name() << endl; //int //b,c,e是同一块内存 cin.get(); } #include <iostream> using namespace std; void main() { const int a1{ 10 }; //a1 = 12; //C3892 “a1” : 不能给常量赋值 cout << "const int a1 = "<< a1 << " "<< typeid(a1).name() << endl; //int int b1 = a1; //推导:取出a的值赋值给b分配的空间 const auto b2 = a1; //b是新内存,是const int * b1 = 12; // b2 = 12; //C3892 “b2” : 不能给常量赋值 cout << "int b1 = " << b1 << " " << typeid(b1).name() << endl; //int auto c0 = a1; //只是将a1的值赋值过来,是int类型 c0 = 12; cout << "auto c0 = " << c0 << " " << typeid(c0).name() << endl; //int &c1 = a1; //C2440 “初始化” : 无法从“const int”转换为“int &” 、 auto &c1 = a1; //b和c是同一块内存 // c1 = 12; //C3892 “c1” : 不能给常量赋值 cout << "auto &c1 =" << c1 << " " << typeid(c1).name() << endl; cin.get(); }总结:如果初始化表达式为const或volatile(或者两者兼有),则除去const/volatile语义。如果auto关键字带上&号,则不去除const语意。=是赋值,&是别名
使用auto时,当传递的是const变量的时候,必须手动加上const,因为auto不会自动推倒成const,除非和引用连用。 #include <iostream> using namespace std; void main() { const int a = 1; const auto b = a; //b是const auto auto c = a;//c的类型为int auto& d = a;//d的类型为const int & cin.get(); }总结:auto i是一个副本,会将数组元素原样赋值给i
如果要修改auto副本:for(auto &i : a),也就是声明为引用
#include <iostream> using namespace std; void main() { int a[5]{ 1, 2, 3, 4, 5 }; for (auto &i : a) { i += 1; cout << i << endl; //2,3,4,5, 6 } for (auto i : a) { cout << i << endl; //2,3,4,5, 6 } cin.get(); }
