C++11范圍for循環


范圍for循環:
1.基於范圍的for循環
for(元素類型 元素對象:容器對象)
{
  循環體
}
(1.1)如果循環體由單條語句或者單個結構塊組成,可以省略花括號
(1.2)用元素對象依次結合容器對象中的每一個元素,每結合一個元素,執行依次循環體,直至容器內的所有元素都被結合完為止.
(1.3)不依賴於下標元素,通用
(1.4)不需要訪問迭代器,透明
(1.5)不需要定義處理函數,簡潔

#include "stdafx.h"
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
void print(int i)
{
    cout << i << " ";
}

int main()
{
    int ai[]{ 65, 66, 67, 68, 69 };
    //計算數組元素個數
    size_t size = sizeof(ai) / sizeof(ai[0]);
    vector<int> vi(ai, ai + size);
    //基於下標運算的for循環,不是所有的容器都支持下標運算,不通用
    for (size_t i = 0; i < size; ++i)
        cout << ai[i] << " ";
    cout << endl;
    for (size_t i = 0; i < vi.size(); ++i)
        cout << vi[i] << " ";
    cout << endl;
    //基於迭代器的for循環,需要指明容器兩端,且對迭代器做自增,必須了解迭代器的運算規則,不夠透明
    for (int *it = ai; it != ai + size; ++it)
        cout << *it << " ";
    cout << endl;
    for (auto it = vi.begin(); it != vi.end(); ++it)
        cout << *it << " ";
    cout << endl;
    //基於泛型函數的for循環,需要提供針對元素的處理函數,對於一般性遍歷而言比較繁瑣
    for_each(ai, ai + size, print);
    cout << endl;
    for_each(vi.begin(), vi.end(), print);
    cout << endl;
    for (auto a : ai)
        cout << a << " ";
    cout << endl;
    for (auto a : vi)
        cout << a << " ";
    cout << endl;
    for (auto &a : ai)
        ++a;
    for (auto &a : vi)
        --a;
    for (auto const &a : ai)
        cout << a << " ";
    cout << endl;
    for (auto const &a : vi)
        cout << a << " ";
    cout << endl;
    for (char a : ai)
        cout << a << " ";
    cout << endl;
    for (char a : vi)
        cout << a << " ";
    cout << endl;
    return 0;
}

 

2.范圍循環的注意事項
(2.1)對map和multimap容器使用范圍循環,每次拿到的元素既不是鍵也不是值,而是由鍵和值組成的pair
(2.2)在使用基於范圍的for循環時,不能違背容器本身的約束
(2.3)基於范圍的for循環,無論循環體執行多少次,冒號后面的表達式永遠只執行一次
(2.4)基於范圍的for循環,其底層實現依然要借助於容器的迭代器,
因此任何可能導致迭代器失效的結構性改變,都可能引發未定義的后果

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

list<int> getScores(void)
{
    cout << __FUNCTION__ << endl;
    return{ 70, 75, 80, 85, 90, 95 };
}

int main()
{
    //對map和multimap容器使用范圍循環,每次拿到的元素既不是鍵也不是值,而是由鍵和值組成的pair
    multimap<string, int> msi;
    msi.insert(make_pair("張飛", 100));
    msi.insert(make_pair("趙雲", 90));
    msi.insert(make_pair("關羽", 80));
    for (auto c : msi)
        cout << c.first << ":" << c.second << endl;
    cout << endl;
    for (auto it = msi.begin(); it != msi.end(); ++it)
        cout << it->first << ":" << it->second << endl;
    cout << endl;

    //在使用基於范圍的for循環時,不能違背容器本身的約束
    /*for (pair<string,int> &c:msi)
    if (c.first == "張飛")
    c.first = "張菲菲";*/
    for (auto c : msi)
        cout << c.first << ":" << c.second << endl;
    cout << endl;
    //基於范圍的for循環,無論循環體執行多少次,冒號后面的表達式永遠只執行一次
    for (auto score : getScores())
        cout << score << " ";
    cout << endl;
    auto scores = getScores();
    for (auto score : scores)
    {
        cout << score << " ";
        //基於范圍的for循環,其底層實現依然要借助於容器的迭代器,
        //因此任何可能導致迭代器失效的結構性改變,都可能引發未定義的后果
        //scores.pop_front();
    }
    cout << endl;
    return 0;
}

 

3.使自己定義的容器類型支持范圍循環
一個類只要提供了分別獲取起始和終止迭代器的begin和end函數,就可以支持基於范圍的for循環

#include "stdafx.h"
#include <iostream>
using namespace std;

template <typename T, size_t S>
class Array
{
public:
    T &operator[](size_t i)
    {
        return m_array[i];
    }
    T const &operator[](size_t i)const
    {
        return const_cast<Array&>(*this)[i];
    }
    //獲取起始迭代器
    T *begin()
    {
        return m_array;
    }
    T const *begin()const
    {
        return const_cast<Array *>(this)->begin();
    }
    //獲取終止迭代器
    T *end()
    {
        return m_array + S;
    }
    T const *end()const
    {
        return const_cast<Array *>(this)->end();
    }
private:
    T m_array[S];
};


int main()
{
    int i = 0;
    Array<int, 5> ai;
    for (auto &a : ai)
        a = ++i * 10;
    auto const &cai = ai;
    for (auto &a : cai)
        cout << /*++*/a << " ";
    cout << endl;
    return 0;
}

 


免責聲明!

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



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