• auto类型-现代C++新特性


    auto类型

    C++11中引入的auto主要用于类型推导。auto在C++98中“存储类型指示符”的语义,由于使用极少且多余,该语义从C++11开始被删除。

    auto类型推导用于从初始化表达式中推断出变量的数据类型,通过此方法可以有效简化代码:

    Example:

    //简化前的代码
    
    for (std::vector<std::string>::iterator i = vs.begin(); i != vs.end(); i++)
    {
    	//code
    }
    
    
    //简化后的代码
    
    for (auto i = vs.begin(); i != vs.end(); i++)
    {
    	//code
    }
    

    上例中,auto能够自动推导出vs.begin()的类型,从而避免了冗长的类型说明。这个用法是我们大力推荐的。


    当auto用于模板定义中,其“自适应”性会得到更充分的体现。

    Example:

    #include<iostream>
    
    template<typename T1, typename T2>
    double Sum(T1 & t1, T2 & t2)  //从c++14起,也可以支持函数返回值类型设为auto,这种用法多用于编写库的开发人员。
    {
    	auto s = t1 + t2;	//s的类型会在模板实例化时被推导出来
    	return s;
    }
    
    int main()
    {
    	int a = 3;
    	long b = 5;
    	float c = 1.0f, d = 2.3f;
    
    	auto e = Sum<int, long>(a, b);		//s的类型被推导为long
    	auto f = Sum<float, float>(c, d);	//s的类型被推导为float
    	std::cout << e << "  " << f << std::endl;
    	
    	return 0;
    }
    
    //编译选项:g++ -std=c++11  auto1.cpp
    

    上例中,由于类型T1、T2要在模板实例化时才能确定,所以在Sum中将变量s的类型声明为auto。


    auto可以与指针和引用结合起来使用,使用效果符合我们的想象。如下例所示:

    Example:

    #include<iostream>
    #include<typeinfo>
    
    int main()
    {
    	int x = 0;
    	int *y = &x;
    
    	auto &b = x;			//int&
    	auto c = y;			    //int*
    	auto *d = y;			//int*
    	auto e = b;				//int
    
    	return 0;
    }
    
    //编译选项:g++ -std=c++11  auto2.cpp
    

    本例中,对于c、d两个变量而言,声明其为auto*或auto并没有区别。

    而如果要使得auto声明的变量是另一个变量的引用,则必须使用auto&,如本例中的变量b。而本例中e没有带&,则被推导成int类型。正如我们所熟知的,使用引用其实是使用引用的对象,特别是当引用被用作初始值时,真正参与初始化的其实是引用对象的值。


    其次,auto与const和volatile之间也存在着一些相互关系。const和volatile代表了变量的两种不同的属性:易失和常量。在c++标准中,它们常常被一起叫作cv限制符(cv-qualifier)。

    在深入介绍auto和cv限定符连用之前,先介绍下C++11中的顶层const和底层const。顶层const(top-level const)表示指针本身是一个常量,而底层const(low-level const)表示指针所指的对象是一个常量。

    更一般的,顶层const可以表示任意的对象是常量,这一点对于任何数据类型都适用,如算术类型、类、指针等。底层const则与指针和引用等复合类型的基本类型部分有关。

    int i = 0;
    int *const p1 = &i;			//顶层const
    const int ci = 42;			//顶层const
    const int *p2 = &ci;		//底层const
    const int *const p3 = p2;	//右边的const是顶层const,左边的const是底层const
    const int &r = ci;			//用于声明引用的const都是底层const
    

    同理,volatile与const的用法相似。


    鉴于cv限制符的特殊性,C++11标准规定auto可以与cv限制符一起使用。在连用时,auto一般会忽略掉顶层const,同时底层const则会保留下来,比如当初始值时一个指向常量的指针时:

    Example:

    int i = 0;
    const int ci = i, &cr = ci;
    auto b = ci;	//b:int(ci的顶层const特性被忽略掉了)
    auto c = cr;	//c:int(cr是ci的别名,ci本身是顶层const)
    auto d = &i;	//d:int *(整数的地址就是指向整数的指针)
    auto e = &ci;	//e:const int *(对常量对象取地址是一种底层const)
    

    如果希望推断出auto类型是一个顶层const,需要明确指出:

    const auto f = ci; //ci的推演类型是int,f是const int
    

    同理volatile与auto连用的用法和const一致。


    auto在使用上的限制:以下四种情况特点基本类似,人为观察很容易能够推导出auto所在位置应有的类型,但现有标准还不支持这样的方式。

    Example:

    #include<vector>
    using namespace std;
    
    void fun(auto x = 1)		//1:auto函数形参,无法通过编译
    {}
    
    struct str
    {
    	auto var = 10;			//2:auto非静态成员变量,无法通过编译
    };
    
    int main()
    {
    	char x[3];
    	auto y = x;
    	auto z[3] = x;			//3:auto数组,无法通过编译
    
    	vector<auto> v = { 1 };	//4.auto模板参数(实例化时,)无法通过编译
    	return 0;
    }
    
    //编译选项:g++ -std=c++11  auto3.cpp
    
    新战场:https://blog.csdn.net/Stephen___Qin
  • 相关阅读:
    react实现拖拽
    JS实现判断滚动条滚到页面底部并执行事件的方法
    获取地址中的参数 封装在params对象里面
    git常用命令
    Linux定时任务Crontab命令详解
    tars 部署
    tars 问题汇总
    Mac
    http head
    SSL
  • 原文地址:https://www.cnblogs.com/Stephen-Qin/p/9387891.html
Copyright © 2020-2023  润新知