C++ Range-based For Loop (for (auto& x : container)) รองรับเฉพาะ Forward Iteration ตั้งแต่ C++11 หากต้องการ Iterate ย้อนหลัง (Reverse) มีหลายวิธี
1. ใช้ Boost.Range (Classic Solution)
Header: <boost/range/adaptor/reversed.hpp>
#include <iostream>
#include <vector>
#include <boost/range/adaptor/reversed.hpp>
int main() {
std::vector<int> v = {11, 44, 77, 55, 44, 22, 33, 30, 88, 99, 55, 44};
std::cout << "Normal: ";
for (auto i : v) std::cout << i << ' ';
std::cout << '\n';
std::cout << "Reversed: ";
for (auto i : boost::adaptors::reverse(v))
std::cout << i << ' ';
// Output: 44 55 99 88 30 33 22 44 55 77 44 11
}
2. ใช้ C++20: std::views::reverse (Standard, Header <ranges>)
#include <iostream>
#include <vector>
#include <ranges> // C++20
int main() {
std::vector<int> v = {1, 2, 3, 4, 5};
std::cout << "Reversed (C++20): ";
for (auto i : v | std::views::reverse)
std::cout << i << ' '; // 5 4 3 2 1
}
3. Manual Reverse Iterator (No Dependency, Pre-C++20)
#include <iostream>
#include <vector>
int main() {
std::vector<int> v = {1, 2, 3, 4, 5};
// Classic Reverse Iterator
std::cout << "Reverse Iterator: ";
for (auto it = v.rbegin(); it != v.rend(); ++it)
std::cout << *it << ' ';
// Index-based (ถ้าต้องการ Index)
std::cout << "\nIndex Reverse: ";
for (size_t i = v.size(); i-- > 0; )
std::cout << v[i] << ' ';
}
4. Custom Reverse View (C++17, No Boost)
#include <iostream>
#include <vector>
#include <iterator>
template <typename Container>
class ReverseView {
Container& c;
public:
ReverseView(Container& c) : c(c) {}
auto begin() const { return c.rbegin(); }
auto end() const { return c.rend(); }
};
template <typename C>
ReverseView<C> make_reverse(C& c) { return ReverseView<C>(c); }
// Usage
int main() {
std::vector<int> v = {1,2,3,4,5};
for (auto i : make_reverse(v)) std::cout << i << ' ';
}
ตารางเปรียบเทียบ
| วิธี | Standard | Dependency | Readability | Performance |
|---|---|---|---|---|
| Boost::adaptors::reverse | ❌ | Boost | ⭐⭐⭐⭐⭐ | Zero Overhead |
| std::views::reverse (C++20) | ✅ | None | ⭐⭐⭐⭐⭐ | Zero Overhead |
| Reverse Iterator (rbegin/rend) | ✅ (C++98) | None | ⭐⭐⭐ | Zero Overhead |
| Index Loop (size_t i = n; i--;) | ✅ | None | ⭐⭐ | Zero Overhead |
ข้อระวัง
- Range-based For ต้องการ
begin()และend()(Non-const สำหรับ Mutable) boost::adaptors::reverseและstd::views::reverseคืน View (Lazy, No Copy)- Container ต้องมี
rbegin()/rend()(Vector, List, Deque, String, Array - แต่ไม่ใช่ Forward List)
สรุป
C++20 std::views::reverse เป็นคำตอบมาตรฐานที่ดีที่สุด ก่อน C++20 ใช้ boost::adaptors::reverse หรือ Manual Reverse Iterator ทั้งคู่ Zero Overhead Abstraction เลือกตาม Compiler Support และ Dependency Policy ของโปรเจกต์