如何使用 forrange 疊代 class 的成員
tags: 部落格文章
什麼是 forrange
這東西其實很好用,也很容易在別的代碼裡看到,他長這個樣子
vector<int> v{1, 2, 3};
for(auto&& i : v)
    cout << i << endl;
上面這個例子就會自己把結果疊代出來了,forrange這個東西展開來其實是用iterator實現的,差不多會等於下面的代碼
for (Vector<int>::iterator it = v.begin() ; it != v.end(); ++it)
    std::cout << *it << std::endl;
由這邊可以看出來我們需要實現的有這幾個大項
- Range::begin();
- Range::end();
- class iterator{};
- iterator::operator==()
- iterator::operator!=()
- iterator::operator*()
建立一個class
首先先讓我們把自己的class建造出來,大概就是簡單管理一個陣列即可。
class Range {
public:
    using _type = int;
public:
    Range(){}
    Range(initializer_list<_type> l): len(l.size()) {
        arr = new _type[l.size()];
        std::copy(l.begin(), l.end(), arr);
    }
    ~Range() {
        delete[] arr;
    }
private:
    _type* arr = nullptr;
    size_t len = 0;
};
iterrator 類別
差不多就這樣簡單即可,接下來要建造一個 iterrator 的類別(直接包在類別內就可以),還有完成剛剛提到那幾個函式。
在這個類別裡需要兩個成員資料,一個是我們自己建造的類別,一個是當前的指針跑到第幾個了。
struct Iterator {
    private:
        Range const* r;
        int current;
}
接下來是個別的函式
    struct Iterator {
    public:
        Iterator(Range const* x, size_t c) : r(x), current(c) {}
        Iterator& operator++() {
            ++current;
            return *this;
        }
        Iterator operator++(int) {
            Iterator old = *this;
            operator++();
            return old;
        }
        const _type& operator*() const{
            return r->arr[current];
        }
        friend bool operator==(Iterator const& x, Iterator const& y) {
            return x.current == y.current;
        }
        friend bool operator!=(Iterator const& x, Iterator const& y) {
            return !(x == y);
        }
    private:
        Range const* r;
        int current;
    };
建造好之後就可以使用摟
完整範例
#include <iostream>
#include <Iterator>
#include <initializer_list>
using namespace std;
class Range {
public:
    using _type = int;
public:
    Range(){}
    Range(initializer_list<_type> l): len(l.size()) {
        arr = new _type[l.size()];
        std::copy(l.begin(), l.end(), arr);
    }
    ~Range() {
        delete[] arr;
    }
private:
    _type* arr = nullptr;
    size_t len = 0;
public:
    struct Iterator {
    public:
        Iterator(Range const* x, size_t c) : r(x), current(c) {}
        Iterator& operator++() {
            ++current;
            return *this;
        }
        Iterator operator++(int) {
            Iterator old = *this;
            operator++();
            return old;
        }
        const _type& operator*() const{
            return r->arr[current];
        }
        friend bool operator==(Iterator const& x, Iterator const& y) {
            return x.current == y.current;
        }
        friend bool operator!=(Iterator const& x, Iterator const& y) {
            return !(x == y);
        }
    private:
        Range const* r;
        int current;
    };
    Iterator begin() const {
        return Iterator(this, 0);
    }
    Iterator end() const {
        return Iterator(this, len);
    }
};
int main() {
    Range r{1, 2, 3};
    for (auto&& i : r) {
        cout << i << ", ";
    } cout << endl;
}
