auto与decltype

auto:用来声明自动变量。它是存储类型标识符,表明变量(自动)具有本地范围,块范围的变量声明(如for循环体内的变量声明)默认为auto存储类型。
其实大多普通声明方式声明的变量都是auto变量,他们不需要明确指定auto关键字,默认就是auto的了。auto变量在离开作用域是会变程序自动释放,不会发生内存溢出情况(除了包含指针的类)。使用auto变量的优势是不需要考虑去变量是否被释放,比较安全吧。
new:new是用来在堆上申请内存地址的关键字,他产生的变量不会自动释放,除非delete来手动释放,或者程序结束时由操作系统释放,使用new的优势是内存使用比较灵活,理论可以申请任意大小的内存区块(实际与操作系统有关),但这很容易产生问题,一不小心忘记释放对象,特别是在频繁调用的函数内创建的对象忘记释放时,会产生内存溢出,严重时导致程序出错,系统崩溃。new一般都是在类的定义中使用,结合delete可以使包含new出来对象的类也具有自带变量功能,这样就继承了两种方式的优势。
--------------------------------------------------------------
另外,最新的C++标准更新了auto关键字的功能
除了具有原有的含义外,还增加了一种类似其他高级语言的型别推导特性
使用auto来代替变量的类型,
前提是被明确类型的初始化变量初始化的,可以使用auto关键字
比如int i=10; auto a = i; //这样a也是int类型了
这在使用一些模板类的时候,对于减少冗赘的代码也很有用
---------------------------------------------------------------
另外一个题外话:auto的对应类型不是使用new出来的变量,而是static变量
static变量是程序接收的时候才释放对象的,但它不需要手动释放。
static如果在一个函数内申明,这每次进入这个函数时,还是使用第一次声明的变量,并且还保存的上次使用的值(auto变量这时函数结束是即释放了,再次调用这个函数是,有重新定义了一个新的变量)
static变量如果在结构和类中使用,这结构或类定义的一切对象,都将共享唯一static变量。

一、auto关键字的前世

从C语言开始,auto关键字就被当作是一个变量的存储类型修饰符,表示自动变量(局部变量)。它不能被单独使用,否则编译器会给出警告。

#include <stdio.h>int main(){
        int a = 123;
        auto int b = 234;
        auto c = 345;

        printf("a = %d, b = %d, c = %d
", a, b, c);
        return 0;}

编译运行结果:

$ gcc main.c
main.c:7:7: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
        auto c = 345;
        ~~~~ ^1 warning generated.$ ./a.out 
a = 123, b = 234, c = 345

二、auto关键字的今生

在C++ 11标准中,添加了新的类型推导特性,考虑到auto关键字很少使用,就给它重新赋予了功能——申明类型由编译器推导的变量。在C++ 11中,使用auto定义的变量不能使用其它类型修饰符修饰,该变量的类型由编译器根据初始化数据自动确定。auto类型的变量必须进行初始化。

#include <iostream>int main(){
        int a = 21;
        auto b = a;

        //typeid可以获取变量或者数据类型的名字
        std::cout << typeid(b).name() << std::endl;

        return 0;}

1 .使用C++ 98标准进行编译,会出现警告:

$ clang++ main.cpp -std=c++98
main.cpp:6:2: warning: 'auto' type specifier is a C++11 extension
      [-Wc++11-extensions]
        auto b = a;
        ^1 warning generated.$ ./a.out 
i                   #输出结果为整数类型

改用C++ 11进行编译:

$ clang++ main.cpp -std=c++11$ ./a.out 
i

2 .但是如果还是将auto作为存储类型修饰符使用,则在C++ 11标准下会出现警告:

#include <iostream>int main(){
        int a = 21;
        auto int b = a;

        //typeid可以获取变量或者数据类型的名字
        std::cout << typeid(b).name() << std::endl;

        return 0;}

使用C++ 98编译:

$ clang++ main.cpp -std=c++98$ ./a.out 
i

改用C++ 11编译,出现警告,不再允许作为存储类型修饰符使用:

$ clang++ main.cpp -std=c++11
main.cpp:6:2: warning: 'auto' storage class specifier is not permitted in C++11,
      and will not be supported in future releases [-Wauto-storage-class]
        auto int b;
        ^~~~~1 warning generated.

3 .必须要对auto类型的变量进行初始化,C++ 98中不能单独使用auto定义变量。

$ clang++ main.cpp -std=c++98
main.cpp:6:2: warning: 'auto' type specifier is a C++11 extension
      [-Wc++11-extensions]
        auto b;
        ^
main.cpp:6:7: error: declaration of variable 'b' with type 'auto' requires an
      initializer
        auto b;
             ^1 warning and 1 error generated.$ clang++ main.cpp 
main.cpp:6:2: warning: 'auto' type specifier is a C++11 extension
      [-Wc++11-extensions]
        auto b;
        ^
main.cpp:6:7: error: declaration of variable 'b' with type 'auto' requires an
      initializer
        auto b;
             ^1 warning and 1 error generated.

三、扩展

在C++中还能使用decltype来获取变量或者表达式的类型并用来定义新的变量。

#include <iostream>int main(){
        int a = 21;
        decltype(a) b;

        std::cout << typeid(b).name() << std::endl;

        return 0;}

编译运行结果:

$ clang++ main.cpp -std=c++98$ ./a.out 
i$ clang++ main.cpp -std=c++11$ ./a.out 
i

 

原文地址:https://www.cnblogs.com/yjds/p/8597215.html