Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> C++

Vòng lặp for dựa trên phạm vi ngược (Reverse Range-based for) trong C++11

C++11 giới thiệu range-based for loop, nhưng không có sẵn phiên bản ngược. Có thể dùng Boost.Range với boost::adaptors::reverse để duyệt container ngược.

Yêu cầu

  • Cài đặt Boost library
  • Include <boost/range/adaptor/reversed.hpp>

Ví dụ với std::list

#include <list>
#include <iostream>
#include <boost/range/adaptor/reversed.hpp>

using namespace std;

int main() {
    std::list<int> x {11, 44, 77, 55, 44, 22, 33, 30, 88, 99, 55, 44};
    
    cout << "Vong lap thuan:" << endl;
    for (auto i : x) {
        cout << i << '\n';
    }
    
    cout << "\nVong lap nguoc (Boost):" << endl;
    for (auto i : boost::adaptors::reverse(x)) {
        cout << i << '\n';
    }
}

Kết quả

Vong lap thuan:
11
44
77
55
44
22
33
30
88
99
55
44

Vong lap nguoc (Boost):
44
55
99
88
30
33
22
44
55
77
44
11

Cách hoạt động

boost::adaptors::reverse trả về một adaptor (wrapper) cung cấp begin() và end() ngược lại của container gốc. Range-based for loop dùng các iterator này.

Phương án thay thế không cần Boost (C++11 thuần)

1. Dùng index (cho container có random access)


vector<int> v = {1, 2, 3, 4, 5};
for (size_t i = v.size(); i-- > 0; ) {
    cout << v[i] << " ";
}

2. Dùng reverse_iterator


for (auto it = v.rbegin(); it != v.rend(); ++it) {
    cout << *it << " ";
}

3. Tự viết adaptor đơn giản (C++11)


template <typename C>
struct Reversed {
    C& c;
    auto begin() const { return c.rbegin(); }
    auto end() const { return c.rend(); }
};

template <typename C>
Reversed<C> reversed(C& c) { return {c}; }

// Sử dụng:
for (auto x : reversed(v)) { cout << x << " "; }

C++20: std::views::reverse


#include <ranges>
#include <vector>
#include <iostream>

int main() {
    vector<int> v = {1, 2, 3, 4, 5};
    for (int x : v | std::views::reverse) {
        cout << x << " ";
    }
}

So sánh

Phương phápYêu cầuHỗ trợ containerĐộ phức tạp
Boost::adaptors::reverseBoostTất cả (bidirectional)O(1) setup
reverse_iteratorSTLTất cảO(1)
Index loopSTLRandom accessO(1)
C++20 views::reverseC++20Tất cả (bidirectional)O(1)

Khuyến nghị

  • Đã có Boost: Dùng boost::adaptors::reverse
  • Chỉ STL: Dùng rbegin()/rend() hoặc tự viết adaptor
  • C++20: Dùng std::views::reverse (chuẩn, không phụ thuộc Boost)