首页 > 编程语言 >C++ 11 auto关键字

C++ 11 auto关键字

时间:2023-10-12 16:47:30浏览次数:53  
标签:11 变量 auto C++ 关键字 类型 声明

https://www.cnblogs.com/DswCnblog/p/5629048.html 熟悉脚本语言的人都知道,很多脚本语言都引入了“类型自动推断”技术:比如Python,可以直接声明变量,在运行时进行类型检查。随着C++11标准的发布,C++语言也引入了类型自动推断的功能,这就是我们今天要介绍的auto关键字。

C++是一种强类型语言,声明变量时必须明确指出其类型。但是,在实践中,优势我们很难推断出某个表达式的值的类型,尤其是随着模板类型的出现,要想弄明白某些复杂表达式的返回类型就变得更加困难。为了解决这个问题,C++11重新定义了auto关键字的语义,用于进行自动类型推断。为什么说“重新定义”呢?auto关键字在C++98中已经出现,用于自动变量的声明,但是极少被使用(关于此定义,可以查看这里)。

用法

C++引入auto关键字主要有两种用途:一是在变量声明时根据初始化表达式自动推断该变量的类型,二是在声明函数时作为函数返回值的占位符。对于自动类型推断,C++11中也有一个类似的关键字decltype,感兴趣的童鞋可以继续关注我的博客,今天我们主要来讲解一些auto关键字的用法。

自动类型推断

使用auto从初始化表达式中推断出变量的数据类型,可以大大简化我们的编程工作,特别是对于一些类型冗长复杂的变量。比如,在以前的做法中,对于vector类型的变量,如果我们需要获取它的迭代器,我们需要这样声明vector::iterator iter,而使用auto关键字后我们可以让编译器帮我们推断出迭代器的具体类型。另外,在模板函数定义时,如果变量的类型依赖于模板参数,我们也很难确定变量的类型,使用auto关键字则可以把这些“脏活累活”交给编译器完成。

下面看一些简单的例子:

复制代码
#include <iostream>
#include <vector>
using namespace std;

template<class T, class U>
void add(T t, U u)
{
    auto s = t + u;
    cout << "type of t + u is " << typeid(s).name() << endl;
}

int main()
{
    // 简单自动类型推断
    auto a = 123;
    cout << "type of a is " << typeid(a).name() << endl;
    auto s("fred");
    cout << "type of s is " << typeid(s).name() << endl;

    // 冗长的类型说明(如迭代器)
    vector<int> vec;
    auto iter = vec.begin();
    cout << "type of iter is " << typeid(iter).name() << endl;

    // 使用模板技术时,如果某个变量的类型依赖于模板参数,使用auto确定变量类型
    add(101, 1.1);
}
复制代码

函数返回值占位符

在这种情况下,auto主要与decltype关键字配合使用,作为返回值类型后置时的占位符。此时,关键字不表示自动类型检测,仅仅是表示后置返回值的语法的一部分。

示例如下:

template<class T, class U>
auto add(T t, U u) -> decltype(t + u) 
{
    return t + u;
}

注意事项

1、使用auto关键字的变量必须有初始值。

2、可以使用valatile,*(指针类型说明符),&(引用类型说明符),&&(右值引用)来修饰auto关键字。

复制代码
    auto a = 10;
    auto *pa = new auto(a);
    auto **rpa = new auto(&a);
    cout << typeid(a).name() << endl;   // 输出: int
    cout << typeid(pa).name() << endl;  // 输出: int *
    cout << typeid(rpa).name() << endl; // 输出: int **
复制代码

3、函数参数和模板参数不能被声明为auto。

4 、使用auto关键字声明变量的类型,不能自动推导出顶层的CV-qualifiers和引用类型,除非显示声明。例如:

  • 使用auto关键字进行类型推导时,如果初始化表达式是引用类型,编译器会去除引用,除非显示声明。例如:
复制代码
    int i = 10;
    int &r = i;
    auto a = r;
    a = 13; // 重新赋值
    cout << "i = " << i << " a = " << a << endl;    // 输出i=10,a=13

    // 显式声明
    auto &b = r;
    b = 15; // 重新赋值
    cout << "i = " << i << " b = " << b << endl;    // 输出i=15,a=15
复制代码
  • 使用auto使用auto关键字进行类型推导时,编译器会自动忽略顶层const,除非显示声明。例如:
复制代码
    const int c1 = 10;
    auto c2 = c1;
    c1 = 11; // 报错,c1为const int类型,无法修改const变量
    c2 = 14; // 正确,c2为int类型

    // 显示声明
    const auto c3 = c1;
    c3 = 15; // 报错,c3为const int类型,无法修改const变量
复制代码

5、对于数组类型,auto关键字会推导为指针类型,除非被声明为引用。例如:

复制代码
    int a[10];
    auto b = a;
    cout << typeid(b).name() << endl;   // 输出:int *

    auto &c = a;
    cout << typeid(c).name() << endl;   // 输出:int [10]
复制代码

 

标签:11,变量,auto,C++,关键字,类型,声明
From: https://www.cnblogs.com/tomato-haha/p/17759830.html

相关文章

  • 测试4 20211102尹子扬静态库的测试
    1.首先,编译你的模块源代码成为目标文件(.o文件)。例如,如果有一个模块名为mymath.c,你可以使用以下命令来生成目标文件:点击查看代码gcc-cmymath.c-omymath.o请确保你以适当的方式编译所有的模块源代码文件。2.将所有目标文件打包成一个静态库文件。你可以使用ar命令来......
  • getMonth():获取当前月(注意:返回数值为0~11,需要自己+1来显示),0代表一月份,如果要显示2位
    getMonth():获取当前月(注意:返回数值为0~11,需要自己+1来显示),0代表一月份,JavaScriptDate对象 日期选择控件的主要功能是向用户提供包含年、月、日的日期数据并并允许用户对其修改。如果要捕获用户修改日期选择控件的数据事件响应,需要为DataPicker添加一个OnDateChangedListene......
  • Code-C++-chrono to tm (format time)
    Code-C++-chronototm(formattime)std::chrono::system_clock::time_pointnow=std::chrono::system_clock::now(); std::time_tnow_time_t=std::chrono::system_clock::to_time_t(now); std::tm*now_tm=std::localtime(&now_time_t); charbuffer[128......
  • Code-C++-Snowflake
    Code-C++-Snowflake#include<iostream>#include<chrono>#include<stdexcept>classSnowflake{private://雪花算法的各个参数staticconstexprint64_tworkerIdBits=5;staticconstexprint64_tdatacenterIdBits=5;staticcons......
  • C++ 11 Lambda表达式
    C++11Lambda表达式 C++11的一大亮点就是引入了Lambda表达式。利用Lambda表达式,可以方便的定义和创建匿名函数。对于C++这门语言来说来说,“Lambda表达式”或“匿名函数”这些概念听起来好像很深奥,但很多高级语言在很早以前就已经提供了Lambda表达式的功能,如C#,Python等......
  • 智能充电未来之路:ISO 15118-20的关键角色
    随着越来越多的电动汽车进入到大众的视野,对电动汽车的充电技术要求也变得越来越高,在ISO15118协议中表明,电动汽车可以使用智能充电的方式进行充电,可以大大提高充电效率。  ISO15118  ISO15118是一项国际标准,定义了电动汽车和充电桩之间的通信协议,这项标准包括了车辆与......
  • 开发者笔记 C++11新特性并发编程future
    上一篇介绍了<thread>文件里线程相关类,这篇将介绍C++<future>头文件里线程类,future里包含的类主要是处理异步任务,线程函数封装,线程间通信,同步,捕捉异常处理https://zhuanlan.zhihu.com/p/509118687future的引入c++11引入的future是为了解决异步通信问题的。future可以看做是数......
  • C++11新特性之基本范围的For循环(range-based-for)
    C++11新特性之基本范围的For循环(range-based-for)最新推荐文章于 2023-07-2219:30:58 发布Rayen0715于2017-01-0713:49:35发布49588收藏174版权Range-Based-For熟悉C++98/......
  • 10.11
    又是运气爆表的一天!8.10切A,线段树板子看了一眼发现B有点像贪心,但是不太会,开C9.40切C换根板子,并且考过回去看B,想了想会了10.50切B打了个T4的暴力+剪枝检查跑路应得分数400=100+100+100+80实得分数372=100+92+100+80最高分400=100+100+100+100......
  • C++异步定时器设计与实现
    C++异步定时器设计与实现由于目前C++标准中没有现成的定时器,本设计使用C++11相关语法并进行封装。本定时器包含一个TimerManager类用于创建定时器和进行定时任务管理,TimerManager会创建两个线程(mTimerTickThread、mTimerCallbackThread)分别用于时间处理和函数回调。可以使用Ti......