auto (C++)

✍ dations ◷ 2025-11-30 00:47:33 #C++

auto是C++程序设计语言的关键字。自C++11以来,auto关键字用于两种情况:声明变量时根据初始化表达式自动推断该变量的类型、声明函数时函数返回值的占位符。C++98标准中auto关键字用于自动变量的声明,但由于使用极少且多余,在C++11中已删除这一用法。

auto可以在声明变量时根据变量初始值的类型自动为此变量选择匹配的类型。C++语言类似的关键字还有decltype。

举例:对于值x=1;即可以声明:int x = 1或long x = 1,也可以直接声明auto x = 1。

其它语言的类似功能包括C#的var关键字。

根据初始化表达式自动推断被声明的变量的类型,如:

 auto f=3.14;      //double auto s("hello");  //const char* auto z = new auto(9); // int* auto x1 = 5, x2 = 5.0, x3='r';//错误,必须是初始化为同一类型

但是,这么简单的变量声明类型,不建议用auto关键字,而是应更清晰地直接写出其类型。

auto关键字更适用于类型冗长复杂、变量使用范围专一时,使程序更清晰易读:

 std::vector<int> vect;  for(auto it = vect.begin(); it != vect.end(); ++it) {  //it的类型是std::vector<int>::iterator    std::cin >> *it;  }

或者保存lambda表达式类型的变量声明:

  auto ptr = (double x){return x*x;};//类型为std::function<double(double)>函数对象

在模板函数定义时,如果变量的类型依赖于模板参数,使用auto关键字使得在编译期确定这些类型,如:

 template <class T, class U>void Multiply(T t, U u) {      auto v = t * u;      std::cout<<v; }

模板函数的返回类型如果也是依赖于从模板参数推导,

 template <typename _Tx, typename _Ty> auto multiply(_Tx v1, _Ty v2) -> decltype( _Tx * _Ty ) {     return v1*v2; } auto result = multiply(101, 1.414); // 结果类型是double

语义

使用auto关键字做类型自动推导时,依次施加以下规则:

这一组规则同于模板函数的模板参数推导(template argument deduction)时的规则。但auto关键字可以从C++11风格的花括号{与}包围的值列表推导出std::initializer_list;而模板函数的形参推导时不认为这种值列表是一个类型,因此不能由值列表推导出std::initializer_list类型。

因而,使用auto关键字声明变量的类型,不能自动推导出顶层的CV-qualifiers,也不能自动推导出引用类型,需要显式指定。例如:

   const int v1 = 101;   auto v2 = v1;       // v2类型是int,脱去初始化表达式的顶层const   v2=102;            // 可赋值   auto al = { 10, 11, 12 };//类型是std::initializer_list<int>   template<class T> void foo(T arg); // 函数模板声明   foo(v2); //函数模板实例化为 void foo<int>(int)

如果需要具有顶层的CV-qualifiers,或者引用的类型,解决办法是显式指明:

   const auto& v3=v1;   foo<const int&>(v1);//直接指明模板参数类型   template<class T> void foo(const T& arg);//或者偏特化模板函数

如果auto关键字还带上&号,声明引用类型,则不执行const剥除(const-stripping),例如:

   const int c = 0;   auto& rc = c;   rc = 44; // 编译错误,const int类型

这是因为如果不抑制const剥除,则得到了一个非常量引用型变量,指向了const变量,这显然是不可接受的。模板参数推导也遵循此规则。

初始化表达式为数组,auto关键字推导的类型为指针。这是因为数组名在初始化表达式中自动隐式转换为首元素地址的右值。例如:

   int a;   auto j = a;   std::cout << typeid(j).name() << " "<<sizeof(j)<<" "<<sizeof(a)<< std::endl;

由于C++规定字符串字面量是左值,因此可以通过&运算符直接取地址:

   auto al = &"hello";  // a1的类型是const char(*)   

auto关键字的类型完美转发

C++11使用auto声明变量时,如:auto&& var=initValue;“auto&&”并不意味着这一定是右值引用类型的变量,而是类似于模板函数参数的类型推导,既可能是左值引用,也可能是右值引用。其目的是把初始化表达式的值分类情况,完美转发给由auto声明的变量。也即:

相关

  • 蛋白酶蛋白酶(英语:protease)是生物体内的一类酶(酵素),它们能够分解蛋白质。分解方法是打断那些将氨基酸连结成多肽链的肽键。蛋白酶是重要的工业酶,占全球总酶销售量约六成,其中七成用于
  • 纽约证券交易所纽约证券交易所(英语:New York Stock Exchange,英文缩写:NYSE,有时简称纽约证交所或纽交所)与泛欧股票交易所合并前是世界上第二大证券交易所。交易时间为除周末和例行休市日的9:3
  • 卡路里卡路里(Calorie,缩写为cal),简称卡,是一物理学能量单位,其定义为将1克水在1大气压(101.325kPa)下提升1摄氏度所需要的热量。由于科学家发现水在不同温度下的比热容不同,所以衍生了以
  • 班尼奥夫维克托·胡戈·贝尼奥夫(英语:Victor Hugo Benioff,1899年9月14日-1968年2月1日),美国地震学家,加州理工学院教授。他最为人所知的是将太平洋中深层地震发生的深度与震中位置关系绘
  • 理查·莱亚德理查·莱亚德(Richard Layard)是英国顶尖的经济学家,在九十年代末曾担任英国首相布莱尔的顾问。他相信一个社会的快乐不必然与其收入相等,而他所研究的“快乐经济学”(Happiness:
  • 扬中市扬中市是中华人民共和国江苏省镇江市辖下的县级市,位于长江下游。全市由太平洲、中心沙、西沙岛、雷公岛四个江岛组成,在镇江发展全局中具有重要地位。扬中的前身是太平洲,隶属
  • 吴越文化吴越文化,又称“江浙文化”,是指江浙地区的地域文化,其范围大致包括今日的苏南、江西东北的上饶地区皖南和浙江省及上海市,基本与整个吴语方言区(包括有系属争议的徽语)相吻合。吴
  • 油煎煎是常见的烹调方法,指用锅把少量的食用油(烹调用油)加热到摄氏150-200度之间,再把食物放进去,使其熟透。表面会产生美拉德反应而成金黄色乃至微焦,并散发浓烈、特殊的焦香味。
  • 超速传动超速传动是一种传动部件,常用于后轮驱动汽车,让行驶车辆得到极高的齿轮传动比以获得高速的巡航能力,同时在较低扭矩的情况下节省燃料。“超速传动”一词也可以指传动系统中通过
  • 马毓泉马毓泉(1916年2月21日-2008年8月6日),中国江苏省苏州市人,著名植物分类学家。马毓泉1935年考入北京师范大学生物系,次年转入北京大学生物系学习。抗战爆发后,马毓泉投笔从戎,于1938