C++11新特性之auto關鍵字的使用


一.auto關鍵字簡介

auto這個關鍵字並不是一個全新的關鍵字,在舊標准中,它代表的是“具有自動存儲期的局部變量”;但是它在這方面並沒有起到很大的作用,比如:auto int i = 10 與int i = 10是等價的, 在舊標准中我們很少會用到auto關鍵字,因為非靜態變量在默認的情況下本就是“具有自動存儲期的”。

考慮到在舊標准中auto關鍵字用的很少。在C++11新特性中,auto關鍵字不在表示存儲類型指示符,而是把它改成了一個類型指示符,用來提示編譯器對此類型變量做類型的自動推導。

二.auto的推導規則

下述示例需要在支持C++11新特性的編譯器中執行,否則會出現編譯錯誤

#include <iostream>

using namespace std;

int main()
{
    int x = 10;
    auto *a = &x;       //auto被推導為int
    auto b = &x;        //auto被推導為int*
    auto &c = x;        //auto被推導為int
    auto d = c;         //auto被推導為int
    
    const auto e = x;   //auto被推導為int
    auto f = e;         //auto被推導為int
        
    const auto& g = x;  //auto被推導為int
    auto& h = g;        //auto被推導為int

    return 0;
}

A.d的推導結果說明了當表達式是一個引用類型時,auto會把引用類型拋棄,直接推導成原始類型int;

B.f的推導結果說明了當表達式帶有const屬性時,auto會把const屬性拋棄掉,直接推導成int類型;

C.g和h的推導說明了當auto和引用(換成指針在這里也將得到同樣的結果)結合時,auto的推導將保留變量的const屬性

下面是上述推導A的驗證實例

#include <iostream>

using namespace std;

int main()
{
    int x = 10;
    const auto z = x;
    auto y = z;
    y = 10;
    cout << y << endl;

    const int a = 10;
    a = 20;
    cout << a << endl;

    return 0;
}

在C++中,const int a = 10;初始化完成后,在為a賦值為20,編譯器便會報錯。如下所示:

a現在只是一個可讀變量,不可在更改它的初始值;所以說,如果上述y變量類型推導為const int,再為y賦值的話,在編譯時會報出同樣的錯誤,但在編譯時並未出現上述錯誤,那就說明在進行類型推導時,把const屬性給拋棄掉了,只保留了一個原始類型int.

下面是上述推導C的驗證實例

#include <iostream>

using namespace std;

int main()
{
    int x = 10;
    const auto& z = x;
    z = 20;
    cout << z << endl;

    return 0;
}

編譯后會出現如下錯誤:

可以看出z只是一個只讀引用,即const int &類型,不能再為其賦值。

從以上示例可以總結出下面兩條規則

(1).當不聲明為指針或引用時,auto的推導結果和初始化表達式拋棄引用和cv限定符(const和volatile限定符的統稱)。

(2).當聲明為指針或引用時,auto的推導結果將保持初始化表達式的cv屬性。

三.auto的使用范圍

auto關鍵字不是說在任何地方都能適用的;

(1).不能作為函數的形參

(2).不能用於非靜態成員變量

(3).auto無法定義數組

(4).auto無法推導出模板參數

示例如下:

#include <iostream>
#include <list>
using namespace std;

struct MyStruct
{
    auto nValue = 0;  //錯誤: 非靜態的成員變量
    static const auto value = 10;
};

void MyPrintf(auto i) //警告:在參數聲明中使用“auto”只能用-STD= C++1Y或-STD= GNU+1Y:
{
    cout << i << endl;
}

int main()
{
    auto array[10] = {0};   //錯誤:無法定義數組
    list<auto> MyList;      //錯誤:無法推導出模板的參數類型
    auto i = 10;
    MyPrintf(i);
    return 0;
}

那么在什么時候使用auto關鍵字呢?當變量定義過於冗長時,可以考慮使用auto關鍵字代替;比如說C++去遍歷一個stl容器,迭代器定義時比較累贅,換成auto關鍵之后是不是瞬間清爽了不少。

#include <iostream>
#include <vector>

using namespace std;

int main()
{
    vector<int> MyVector;
    //插入數據
    for(int i = 0; i < 10; i++)
    {
        MyVector.push_back(i);
    }
    //舊特性中遍歷數據
    vector<int>::iterator it = MyVector.begin();
    for(; it != MyVector.end(); it++)
    {
        cout << *it <<",";
    }
    cout << endl;
    //新特性中遍歷數據
    auto MyIt = MyVector.begin();
    for(; MyIt != MyVector.end(); MyIt++)
    {
        cout << *MyIt << ",";
    }
    return 0;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM