C++11常用新特性——自动推导类型auto

自动推导类型auto

在C++11之前,auto关键字用于指定变量的存储期,但在C++11中,它的功能被改为类型推导。

auto现在成了一个类型的占位符,它告诉编译器查看变量的初始化器表达式,并使用该表达式的类型来确定变量的类型。这对于避免编写冗长的类型名称,特别是涉及模板的类型名称,非常有用。

在没有auto之前,遍历一个容器可能需要以下书写一个迭代器:

cpp 复制代码
vector<int> vec = {1,2,3,4,5};
    for(vector<int>::iterator it = vec.begin(); it != vec.end(); it++){
        cout << *it << endl;
    }

当有了auto之后,可以使用以下代码:

cpp 复制代码
vector<int> vec = {1,2,3,4,5};
for(auto it = vec.begin(); it != vec.end(); it++){
        cout << *it << endl;
    }

auto 与 const 和引用的交互

autoconst和引用结合使用时,auto的行为可能会引起一些困惑。下面来看几个示例:

cpp 复制代码
int x = 0;
const auto n = x;  // 第2行
auto f = n;        // 第3行
const auto& r1 = x; // 第4行
auto& r2 = r1;     // 第5行
第二行 const auto n = x;
  • x 是一个int类型
  • 由于我们使用了const修饰符,所以n的类型为const int
  • 这里的auto被推导为int,然后应用前面的const修饰符
第3行auto f = n;
  • 尽管n是一个const int类型,但当我们使用auto进行类型推导时,const修饰符不会被考虑。
  • 因此f的类型为int
第4行const auto& r1 = x;
  • x 是一个int类型
  • 由于我们使用了const和引用&,所以r1的类型为const int &
  • 这里的auto被推导为int,然后应用了const和引用&修饰符
第5行auto& r2 = r1;
  • r1const int&类型。
  • 但当我们使用auto&进行类型推导时,const修饰符会被考虑。
  • 因此,r2的类型也是const int&
总结
  1. 当类型不为引用时,使用auto进行类型推导将不保留 表达式的const属性。
  2. 当类型为引用时,使用auto进行类型推导将保留 表达式的const属性。

auto 的高级用法

auto除了可以独立使用,还可以与某些具体的类型混合使用,这样auto表示的就是"半个"类型,而不是完整的类型,从而使得类型推导更灵活。下面给出一些示例:

cpp 复制代码
int x = 0;
auto *pt1 = &x; //pt1 为 int *,auto 推导为 int
auto pt2 = &x;  //pt2 为 int*,auto 推导为 int*
auto &r1 = x;   //r1 为 int&,auto 推导为 int
auto r2 = r1;   //r2 为 int,auto 推导为 int

分析

  1. auto \*pt1 = &x; :
    • &x取得的是变量x的地址,其类型是int*
    • auto前面有一个*,所以auto被推导为int,与*结合后,pt1的类型为int*
  2. auto pt2 = &x; :
    • 同样,&x取得的是x的地址,其类型是int*
    • 由于没有任何其他修饰符,auto直接被推导为int*,所以pt2的类型是int*
  3. auto &r1 = x; :
    • x的类型是int
    • auto前面有一个&,因此auto被推导为int,与&结合后,r1的类型为int&
  4. auto r2 = r1; :
    • r1是一个引用,其引用的是int类型。
    • 由于没有其他修饰符,auto直接被推导为int,所以r2的类型是int

auto的限制

  • 不能在函数参数中使用auto

    cpp 复制代码
    void myFunction(auto param) {   // 错误!
        //...
    }
  • 不能将auto用于类的非静态成员变量。

    cpp 复制代码
    class MyClass {
        auto myVar = 10;    // 错误!
    };

    就是没有static关键字修饰的成员变量

  • 不能将auto用于模板参数。

    cpp 复制代码
    template<auto T>  // 错误!
    class MyTemplateClass {
        // ...
    };
  • 不能用于推导数组类型。

    cpp 复制代码
    int main() {
        int arr[] = {1, 2, 3, 4, 5};
        auto arr2 = arr;  // 错误!
    }

    但可以通过引用的方式来推导:

    cpp 复制代码
    int main() {
        int arr[] = {1, 2, 3, 4, 5};
        auto& arr2 = arr;  // 正确!arr2是对arr的引用
    }

decltype

decltype是"declared type"的缩写,意为"声明的类型"。与sizeof操作符类似,decltype评估表达式的类型,但不实际计算表达式的值。

decltype,在C++中,用于查询表达式的数据类型的操作符,该操作不是实际执行该表达式。这个特性在泛型编程和模板元变成中尤其有用,以解决由于有些类型有模板参数决定,而难以(甚至是不能)表达式的问题。

auto不同的是,auto关键字允许对变量的类型进行自动推导,它主要是基于变量的初始化表达式来工作的。decltype允许我们基于任何给定的表达式来查询类型,而不仅仅是初始化表达式。

对于lambda表达式,如果我们想要在其他地方使用它的类型,我们需要decltype

相关推荐
随便昵称16 分钟前
蓝桥杯专项复习——前缀和和差分
c++·算法·前缀和·蓝桥杯
commonbelive20 分钟前
团体程序设计天梯赛——L1-100 四项全能
c++
genispan23 分钟前
QT/C++ 多线程并发下载实践
开发语言·c++·qt
小卡皮巴拉1 小时前
【力扣刷题实战】矩阵区域和
开发语言·c++·算法·leetcode·前缀和·矩阵
Pacify_The_North1 小时前
【C++进阶三】vector深度剖析(迭代器失效和深浅拷贝)
开发语言·c++·windows·visualstudio
神里流~霜灭2 小时前
蓝桥备赛指南(12)· 省赛(构造or枚举)
c语言·数据结构·c++·算法·枚举·蓝桥·构造
扫地的小何尚2 小时前
NVIDIA工业设施数字孪生中的机器人模拟
android·java·c++·链表·语言模型·机器人·gpu
Zfox_2 小时前
【C++项目】从零实现RPC框架「四」:业务层实现与项目使用
linux·开发语言·c++·rpc·项目
我想吃余2 小时前
【C++篇】类与对象(上篇):从面向过程到面向对象的跨越
开发语言·c++
想睡hhh2 小时前
c++概念——入门基础概念
开发语言·c++