文档章节

C++11新特性之auto关键字的使用

o
 osc_wws45aot
发布于 2019/08/20 14:16
字数 1088
阅读 14
收藏 0

精选30+云产品,助力企业轻松上云!>>>

一.auto关键字简介

auto这个关键字并不是一个全新的关键字,在旧标准中,它代表的是“具有自动存储期的局部变量”;但是它在这方面并没有起到很大的作用,比如:auto int i = 10 与int i = 10是等价的, 在旧标准中我们很少会用到auto关键字,因为非静态变量在默认的情况下本就是“具有自动存储期的”。

考虑到在旧标准中auto关键字用的很少。在C++11新特性中,auto关键字不在表示存储类型指示符,而是把它改成了一个类型指示符,用来提示编译器对此类型变量做类型的自动推导。

二.auto的推导规则

下述示例需要在支持C++11新特性的编译器中执行,否则会出现编译错误

#include <iostream>

using namespace std;

int main()
{
    int x = 10;
    auto *a = &x;       //auto被推导为int
    auto b = &x;        //auto被推导为int*
    auto &c = x;        //auto被推导为int
    auto d = c;         //auto被推导为int
    
    const auto e = x;   //auto被推导为int
    auto f = e;         //auto被推导为int
        
    const auto& g = x;  //auto被推导为int
    auto& h = g;        //auto被推导为int

    return 0;
}

A.d的推导结果说明了当表达式是一个引用类型时,auto会把引用类型抛弃,直接推导成原始类型int;

B.f的推导结果说明了当表达式带有const属性时,auto会把const属性抛弃掉,直接推导成int类型;

C.g和h的推导说明了当auto和引用(换成指针在这里也将得到同样的结果)结合时,auto的推导将保留变量的const属性

下面是上述推导A的验证实例

#include <iostream>

using namespace std;

int main()
{
    int x = 10;
    const auto z = x;
    auto y = z;
    y = 10;
    cout << y << endl;

    const int a = 10;
    a = 20;
    cout << a << endl;

    return 0;
}

在C++中,const int a = 10;初始化完成后,在为a赋值为20,编译器便会报错。如下所示:

a现在只是一个可读变量,不可在更改它的初始值;所以说,如果上述y变量类型推导为const int,再为y赋值的话,在编译时会报出同样的错误,但在编译时并未出现上述错误,那就说明在进行类型推导时,把const属性给抛弃掉了,只保留了一个原始类型int.

下面是上述推导C的验证实例

#include <iostream>

using namespace std;

int main()
{
    int x = 10;
    const auto& z = x;
    z = 20;
    cout << z << endl;

    return 0;
}

编译后会出现如下错误:

可以看出z只是一个只读引用,即const int &类型,不能再为其赋值。

从以上示例可以总结出下面两条规则

(1).当不声明为指针或引用时,auto的推导结果和初始化表达式抛弃引用和cv限定符(const和volatile限定符的统称)。

(2).当声明为指针或引用时,auto的推导结果将保持初始化表达式的cv属性。

三.auto的使用范围

auto关键字不是说在任何地方都能适用的;

(1).不能作为函数的形参

(2).不能用于非静态成员变量

(3).auto无法定义数组

(4).auto无法推导出模板参数

示例如下:

#include <iostream>
#include <list>
using namespace std;

struct MyStruct
{
    auto nValue = 0;  //错误: 非静态的成员变量
    static const auto value = 10;
};

void MyPrintf(auto i) //警告:在参数声明中使用“auto”只能用-STD= C++1Y或-STD= GNU+1Y:
{
    cout << i << endl;
}

int main()
{
    auto array[10] = {0};   //错误:无法定义数组
    list<auto> MyList;      //错误:无法推导出模板的参数类型
    auto i = 10;
    MyPrintf(i);
    return 0;
}

那么在什么时候使用auto关键字呢?当变量定义过于冗长时,可以考虑使用auto关键字代替;比如说C++去遍历一个stl容器,迭代器定义时比较累赘,换成auto关键之后是不是瞬间清爽了不少。

#include <iostream>
#include <vector>

using namespace std;

int main()
{
    vector<int> MyVector;
    //插入数据
    for(int i = 0; i < 10; i++)
    {
        MyVector.push_back(i);
    }
    //旧特性中遍历数据
    vector<int>::iterator it = MyVector.begin();
    for(; it != MyVector.end(); it++)
    {
        cout << *it <<",";
    }
    cout << endl;
    //新特性中遍历数据
    auto MyIt = MyVector.begin();
    for(; MyIt != MyVector.end(); MyIt++)
    {
        cout << *MyIt << ",";
    }
    return 0;
}

 

o
粉丝 0
博文 500
码字总数 0
作品 0
私信 提问
加载中
请先登录后再评论。

暂无文章

Mysql主从同步

1主从同步 1.1Master 1.1.1配置--编辑 my.cnf #编辑 mysql 的 /etc/my.cnf 配置文件vi /etc/my.cnf#添加如下配置server-id=1 #设置服务 IDlog_bin=mysql-bin #启动 binlog...

风雪满弓刀
14分钟前
0
0
修复 `管道菜单“/usr/bin/obamenu”的输出无效 `错误

修复 管道菜单“/usr/bin/obamenu”的输出无效 错误 英文提示应该是 invalid output from pipe-menu "obamenu" 使用 openbox 菜单时碰到了这个错误,上网搜了一下,找到了原因,也就想到了解...

tankb52
28分钟前
13
0
2020最新微信域名防封技术 微信域名防封系统是如何操作的

相信很多朋友在运营自己产品的网站或者是推广链接的时候,经常会发现运行的好好的网站链接突然就被封了,有一部分因为可能是网站的内容触犯了微信的规则,但是还有很大的一部分被同行恶意投诉...

戚馨逸
51分钟前
11
0
mysql 为什么 SQL 语句不要过多的 join?

第一部分 Linux上查看内存的使用情况该用什么命令 free -mh 可以看到内存或者缓存情况 total 总内存 used 已用内存 free 空闲内存 buff/cache 已使用的缓存 avaiable 可用内存 怎么清理已使...

edison_kwok
52分钟前
17
0
芒果TV的金融野心从未停止

来源|WEMONEY研究室 作者|林小林 芒果TV是真的会讲故事,《乘风破浪的姐姐》不仅是生活的故事更是资本的故事,30位姐姐让一款节目累计播放量飙升10亿,同时让背后的上市公司芒果超媒市值站...

镭射财经
今天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部