C++ auto关键字
发布网友
发布时间:2024-10-24 13:31
我来回答
共1个回答
热心网友
时间:2024-11-12 12:42
auto作为C++的关键字,在不同的C++标准中被赋予不同的含义。大致可以分为两个时间段:直到C++ 11之前的auto和C++ 11及以后的auto。
在C++ 98标准中就存在了auto关键字,那时的auto用于声明变量为自动变量(自动变量在控制流进入变量作用域时系统自动为其分配存储空间,并在离开作用域时释放空间),拥有自动的生命周期。但是该作用是多余的,变量默认拥有自动的生命周期。在C++ 11中,已经删除了该用法,取而代之的作用是:自动推断变量的类型。
自从C++ 11开始,编译器可以使用auto关键字自动推断被初始化的变量的类型。auto关键字也被称为占位类型说明符(placeholder type specifier)。通常用法是auto从初始值的类型推断变量本身的类型,变量得到一个初始值的副本。auto会将引用类型推断为值类型。为了确保是引用类型,使用auto&。auto不能推断出const修饰符,为了确保可以推断出,使用const auto。auto&可以推断出const修饰符。
字面常量(Literals)方面,从C++ 14开始,可以识别出字符串常量:从C++ 23开始,可以识别出size_t和有符号的size_t类型。类方面,可以识别出自定义的类:可以识别出list类型:类型名字比较长的类型也可以被auto轻松代替:vector的iterator类型也可以被代替:也可以很容易获得vector中的元素:指针方面,auto也可以推断出指针类型:我们也可以在auto的后面加*来提高阅读性,但是结果和上面是一样的。不论是const auto还是auto const,都是把一个指针变为常量,指针所指的内容是可变的。同样的,我们也可以用*提高可读性。
引用(References)方面,默认情况下,auto会把引用类型推断为值类型。如果你想生成一个比较大的向量(vector)的别名,使用值复制可能会出错。为了避免错误,从C++ 14以后可以使用auto&或者decltype(auto)。使用函数进行初始化的时候,也要注意这一点。const属性方面,如果只使用auto,const属性是不会被推断出来的。必须使用auto&、const auto、const auto&或decltype(auto)。
auto和decltype(auto)方面,仅仅使用auto是不能推断出常量和引用类型。我们必须使用auto&或者const auto,他们可以得到更精确的类型描述。但是有些时候,我们想要编译器自己就可以得到更精确的类型描述,就可以使用decltype(auto)。auto从变量的初始值推断变量的类型:decltype可以推断出表达式的类型,用于变量声明或注入模板。decltype(f())中的f()并没有并调用。在程序运行之前的编译时期,已经推断出是int i,vector v。
结构化绑定(Structured binding)方面,元组(tuple)可以被分解为新的变量:id、message和value被声明为int,string,和double类型。这是一个对元组成员进行命名的好的方法。也可以通过结构化绑定的方式推断出结构体成员。测试(Test)方面,可以通过实验对auto进行测试。比如检查变量类型(注意添加头文件)。为了保证可以正确的推断出变量的类型,可以使用static_assert,如果变量类型不正确,会抛出编译时错误。还可以使用typeid来检查类型是不是正确。输出结果是依赖于编译器的,在我的机器上输出i,m。为了知道他们是什么意思,可以使用命令c++filt -t。对于输出是j的情况,可以使用以下命令:会输出结果unsigned int。typeid没有typetraits可靠。
函数(Function)方面,函数的返回值使用auto来表示时,会根据return语句推断返回值类型(c++ 14)。如果一个函数只是声明了而没有定义会出现错误。如果函数的返回值有多个,不是很明确的情况下,需要明确指定返回值的类型。但是,如果在编译时支持if constexpr语句,函数可以返回不同的类型。c++ 20 允许在函数的参数中使用auto。下面的例子使用容器作为函数的参数,并且容器有size()方法,[]运算符,+运算符。结果类型是自动提升的,比如,vector加上vector是vector。
auto&&是一个通用的引用类型,既可以是左值引用,又可以是右值引用。auto和concepts方面,有时候auto需要被*,这时候我们使用concept。此时以下情况就会报错:所以下面的函数只能是参数是浮点数(float,double)的时候才可以运行。
auto在头文件中方面,在C++ 20中,一个函数的参数是auto类型是被允许的。如果函数的返回类型时auto,必须使用->运算符定义返回类型。GitHub上的一个例子函数参数的类型只和函数作用域相关,但是函数的返回类型和函数被调用的作用域相关。所以头文件中必须指出返回类型。在.cpp文件中,所有的类(此处指模板类)必须被实例化:Lambda函数方面,auto非常适用于识别lambda函数的返回类型。模板Templates方面,auto可以推断出模板函数的返回类型(c++ 14)。如果返回类型对编译器来说不是很清晰,我们可以使用decltype。声明方面,第二节几乎来自对最后一个参考文献的翻译,因为他写的太好了!
参考方面,C++ keywords: auto - cppreference.com Storage class specifiers - cppreference.com Placeholder type specifiers (since C++11) - cppreference.com Function declaration - cppreference.com Structured binding declaration (since C++17) - cppreference.com C++ auto 关键字的使用 - 自由真实个性 - 博客园 (cnblogs.com)自动变量 - 维基百科,自由的百科全书 (wikipedia.org) C++ auto 关键字的使用 (iamsorush.com)