C++简单笔记 - auto关键字-程序员宅基地

技术标签: 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关键字做类型自动推导时,依次施加以下规则:[参 1]

  • 首先,如果初始化表达式是引用,首先去除引用;
  • 上一步后,如果剩下的初始化表达式有顶层的const且/或volatile限定符,去除掉。

这一组规则同于模板函数的模板参数推导(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[9];
auto j = a;
std::cout << typeid(j).name() << " "<<sizeof(j)<<" "<<sizeof(a)<< std::endl

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

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

auto关键字的类型完美转发

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

  • 如果初始化值(initializer)是类型A的左值,则声明的变量类型为左值引用A&;
  • 如果初始化值是类型A的右值,则声明的变量类型为右值引用A&&。
#include<iostream>  
#include <vector>
#include <typeinfo>
using namespace std;
 
struct Widget{
    };
Widget makeWidget(){
     return Widget(); } // 类工厂函数

int main()
{
    
	Widget&& var1 = Widget(); // var1的类型是右值引用,但是作为左值
	auto&& var2 = var1;       //var2的类型是左值引用
	std::vector<int> v = {
     1, 2, 3 };
	auto&& val = v[0]; // std::vector::operator[]的返回值是元素左值,所以val的类型是左值引用
	Widget&& var3 = makeWidget(); // var3是左值,但它的类型是右值引用 
	Widget var4 = static_cast<Widget&&>(var1); // var4是左值,但它的类型是右值引用

	std::cout << typeid(var1).name() << std::endl;
	std::cout << typeid(var2).name() << std::endl;
	std::cout << typeid(val).name() << std::endl;
	std::cout << typeid(var3).name()  << std::endl;
	std::cout << typeid(var4).name() << std::endl;
}

参考文献

  1. C++ auto and decltype Explained, by Thomas Becker
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_50470102/article/details/123231798

智能推荐

HTTP协议详解_审协 许铁柱-程序员宅基地

文章浏览阅读346次。HTTP Request header 当今web程序的开发技术真是百家争鸣,ASP.NET, PHP, JSP,Perl, AJAX 等等。 无论Web技术在未来如何发展,理解Web程序之间通信的基本协议相当重要, 因为它让我们理解了Web应用程序的内部工作. 本文将对HTTP协议进行详细的实例讲解,内容较多,希望大家耐心看。也希望对大家的开发工作或者测试工作有所帮助。使用Fiddler工具非常_审协 许铁柱

canvas与svg_js canvas 画的图保存到svg-程序员宅基地

文章浏览阅读5.4k次。svg和canvas的区别_js canvas 画的图保存到svg

yolo的训练和测试_kotlin yolo-程序员宅基地

文章浏览阅读2.3k次。官网: http://pjreddie.com/yolo/相关文章: http://arxiv.org/abs/1506.02640源代码: https://github.com/pjreddie/darknet.git1 下载源代码2 配置darknet配置darknet ,我之前安装的是openCV3.0.0,无法正常配置darknet在openCV的环境(据说是2_kotlin yolo

HOW TO BUILD QT5(5.15)-程序员宅基地

文章浏览阅读498次。文章目录HOW TO BUILD QT5SynopsisSystem requirementsLicensing:Linux, Mac:Windows:Build!HintsBuilding Qt5 from gitDocumentation简 述: 本文是 qt-everywhere-src-5.15.2.tar.xz 解压后的英文原文的 README 译文,其中文译文可见:如何构建 QT5(5.15)。然后根据此中步骤,成功在 Mac Mojave 中成功编译和运行,其中具体的实战编译参考原文:在 _how to build qt5

计算机电脑配置ppt,计算机应用基础之word2010课件.ppt-程序员宅基地

文章浏览阅读319次。《计算机应用基础之word2010课件.ppt》由会员分享,可在线阅读,更多相关《计算机应用基础之word2010课件.ppt(79页珍藏版)》请在人人文库网上搜索。1、计算机应用基础,第4单元Word2010文字处理软件的应用,中等职业教育规划教材,任务1 创建一个Word文档,目 录,第4单元,任务2 Word文档格式设置,任务4 Word表格操作,任务3 Word文档页面设置,任务5 Wor..._计算机word2010ppt课件

随便推点

Python----获取http请求报文数据_python 从http接受图像数据和文本信息-程序员宅基地

文章浏览阅读8.1k次,点赞4次,收藏5次。Python—-获取http请求报文数据import socketif __name__ == '__main__': # 1.创建tcp服务端套接字 tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 2.绑定端口(端口号可以修改) tcp_server_socket..._python 从http接受图像数据和文本信息

git 合并代码-程序员宅基地

文章浏览阅读3.1w次,点赞5次,收藏64次。一、git 如何把分支代码合并到master1.首先切换到分支;git checkout hellomonkey2.使用git pull 把分支代码pull下来;git pull3.切换到主分支;git checkout master4.把分支的代码merge到主分支;git merge hellomonkey5.git push推上去ok完成,现在 你自己分支的代码就合并到主分支上了。git push总结:同样的道理,主分支的文件也可以合并的分支上。二、git .._git 合并代码

【poj3233】Matrix Power Series——矩阵快速幂_poj3233—矩阵幂序列java-程序员宅基地

文章浏览阅读420次。题目:Matrix Power SeriesTime Limit: 3000MS Memory Limit: 131072KTotal Submissions: 19029 Accepted: 8045DescriptionGiven a n × n matrix A and a positive inte_poj3233—矩阵幂序列java

《笨办法学Python》——习题7_编写一个名为not_bad()的函数,其中包含一个名为sentence的形参。传入一个字符串,-程序员宅基地

文章浏览阅读449次。文章目录基本习题1. 完成基本习题加分习题1. 逆向阅读,在每一行的上面加一行注解2. 倒着朗读出来,找出自己的错误3. 从现在开始,把你的错误记录下来,写在一张纸上4. 在开始下一节习题时,阅读一遍你记录下来的错误,并且尽量避免在下个练习中再犯同样的错误5.记住,每个人都会犯错误。程序员和魔术师一样,他们希望大家认为他们从不犯错,不过这只是表象而已,他们每时每刻都在犯错系统:mac os 10..._编写一个名为not_bad()的函数,其中包含一个名为sentence的形参。传入一个字符串,

Vue - H5 生成带二维码和文案的宣传海报(可自定义二维码扫描后的内容、海报背景图、文案文字、宽高间距等)用 HTML 写可 DIY 的海报,做完后转为图片供用户保存和转发下载_vue二维码自定义背景-程序员宅基地

文章浏览阅读2.3k次,点赞3次,收藏5次。Vue - H5 生成分享宣传海报(含自定义动态二维码和文案),Vue生成二维码分享海报并下载到本地,移动端H5分享海报(含二维码,Vue怎么生成带二维码的推广海报,用户可以长按保存与转发,可以自定义海报内容,自定义标题内容与二维码跳转路径链接文字,h5页面生成分享海报(保存图片、分享),h5在微信生成分享海报(带二维码),前端Vue H5生成带二维码的分享海报,实现长按保存到手机,微信h5页面生成带头像和二维码的海报,分享图片,利用canvas生成二维码海报,qrcodejs2,vue2.x 实现生成海报_vue二维码自定义背景

hdu 1695 GCD (容斥定理+预处理所有数的素因子)_预处理每个数最小素因子-程序员宅基地

文章浏览阅读233次。题目链接:hdu 1695参考链接如下:https://blog.csdn.net/yang_7_46/article/details/9072533 题意:分别在 [ 1, b ] 和 [ 1, d ] 的范围内找出x ,y ( ) ,满足gcd( x, y )=k,问有多少对?注意((5,7)和(7,5))视为一对。 解题思路:由gcd(x,y)=k易得 gcd(x/k ,..._预处理每个数最小素因子