• (转载)【C++11新特性】 auto关键字


    熟悉脚本语言的人都知道,很多脚本语言都引入了“类型自动推断”技术:比如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);
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    函数返回值占位符

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

    示例如下:

    template<class T, class U>
    auto add(T t, U u) -> decltype(t + u) 
    {
        return t + u;
    }
    • 1
    • 2
    • 3
    • 4
    • 5

    注意事项

    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 **
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    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
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 使用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变量
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

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

        int a[10];
        auto b = a;
        cout << typeid(b).name() << endl;   // 输出:int *
    
        auto &c = a;
        cout << typeid(c).name() << endl;   // 输出:int [10]


    原文地址:http://blog.csdn.net/xiejingfa/article/details/50469045

  • 相关阅读:
    java实现二叉树的构建以及三种遍历
    binary-tree-preorder-traversal二叉树的前序遍历
    insertion-sort-list使用插入排序对链表进行排序
    binary-tree-postorder-traversa二叉树的后序遍历
    sort-list
    Redis的数据类型
    在Windows上搭建Redis服务器
    Eureka源码分析
    Eureka概念理解
    Spring Cloud Eureka
  • 原文地址:https://www.cnblogs.com/wodehao0808/p/8251988.html
Copyright © 2020-2023  润新知