讓自定義的容器,也能基於範圍迴圈

ChebyshevTST發表於2023-11-07

  C++11起,引入了基於範圍的for迴圈這一特性,有什麼好處呢?它有時可以大大地簡化遍歷容器的操作,比如說STL的vector。

std::vector v{1, 2, 3};
std::vector<int>::iterator it = begin(v);

for (; it != end(v); ++it)
    std::cout << *it << '\n';

  這是使用了迭代器的寫法,這時候我們的C++11的for迴圈就可以大展身手了。

std::vector v{1, 2, 3};

for (const auto& item : v)
    std::cout << item << '\n';

  當然,除了STL,陣列的遍歷也是沒問題的。接下來到了本篇的主線,假如說我定義了一個資料結構,如下:

template <typename _Tp, std::size_t N>
struct Container {
    using value_type = _Tp;

    _Tp arr[N];

    std::size_t size() {
        return N;
    }

    Container() {
        for (std::size_t i{}; i < N; ++i) 
            arr[i] = i;
    }
};

   這時候當我們也想使用之前的操作的時候,我們會發現

  資訊有點多,不過很容易就注意到了兩個關鍵點,分別是begin和end,我們可以為其提供一個介面看看。

template <typename _Tp, std::size_t N>
struct Container {
    using value_type = _Tp;

    _Tp arr[N + 1];

    std::size_t size() {
        return N;
    }

    Container() {
        for (std::size_t i{}; i < N; ++i) 
            arr[i] = i;
    }

    constexpr _Tp *begin() noexcept {
        return &arr[0];
    }

    constexpr _Tp *end() noexcept {
        return &arr[N];
    }
};

  因為STL的end指標是指向最後一個元素的下一位,所以我們陣列額外開多一個空間,經過此次修改,就能成功執行了。

相關文章