ลูป for แบบ range-based ถูกเพิ่มเข้ามาในมาตรฐาน C++ 11 และเป็นรูปแบบที่กะทัดรัดกว่ารูปแบบดั้งเดิม ลูป for แบบ range-based ใช้สำหรับวนลูปผ่านสมาชิกของคอนเทนเนอร์จากต้นจนจบ Syntax ของลูป for แบบ range-based มีดังนี้:
Syntax
for( range-declaration : range-expression ) loop statement
range-declaration - เป็นการประกาศตัวแปรที่มีชนิดเดียวกับชนิดของสมาชิกใน range-expression บ่อยครั้งใช้คีย์เวิร์ด auto เพื่อระบุชนิดของสมาชิกใน range-expression โดยอัตโนมัติ
range-expression - นิพจน์ใดๆ ที่ใช้แทนลำดับของสมาชิก สามารถใช้ลำดับสมาชิกในเครื่องหมายปีกกาได้ด้วย
loop-statement - ส่วนตัวของลูป for ที่มีคำสั่งหนึ่งหรือหลายคำสั่งที่จะถูกทำซ้ำจนถึงปลายของ range-expression
การเปรียบเทียบกับ for loop แบบดั้งเดิม
// วนลูปอาร์เรย์
int arr[] = { 10, 20, 30, 40, 50 };
for (int num : arr)
printf("%d, ", num);
เทียบเท่ากับ:
for (int i = 0; i < 5; i++)
printf("%d, ", arr[i]);
ที่นี่เห็นได้ง่ายว่าไม่ต้องคำนวณขนาดอาร์เรย์ใน range-based for loop จึงไม่ต้องมีนิพจน์เงื่อนไข (conditional expression) ไม่ต้องมีการเพิ่มหรือลดค่า (increment/decrement) ตัวแปร num ใน range-based for loop ข้างต้นจะรับค่าของสมาชิกจากอาร์เรย์ arr[] ตั้งแต่ต้นจนจบในแต่ละรอบ ไม่มีสมาชิกใดถูกข้ามไป จนกว่าจะมีการใช้ jump statements
Break - หยุดลูปสำหรับรอบที่เหลือทั้งหมด
Continue - ข้ามรอบปัจจุบันไปรอบถัดไป
goto - กระโดดออกจากลูปไปยังคำสั่งตาม label
ข้อดีของ range-based for
- ใช้ง่ายและ syntax เรียบง่าย
- ไม่ต้องคำนวณจำนวนสมาชิกในคอนเทนเนอร์หรือขนาดของ range-expression
- ถ้าชนิดข้อมูลของ range-declaration ไม่รู้ สามารถใช้ auto specifier แทนได้ จะทำให้เข้ากับชนิดของ range-expression อัตโนมัติ
- ไม่ต้องมีคำสั่งเงื่อนไขหรือคำสั่งเพิ่ม/ลดค่า
- เหมาะที่สุดเมื่อต้องการวนลูปทั้งคอนเทนเนอร์ในครั้งเดียว
ข้อเสียของ range-based for
- วนลูปทุกสมาชิกระหว่าง begin() และ end() ไม่สามารถจัดการ index เฉพาะเจาะจงได้
- ไม่สามารถกลับไปเยี่ยมสมาชิกซ้ำ หรือข้ามกลุ่มสมาชิกได้
- ไม่สามารถวนลูปอาร์เรย์ย้อนกลับได้ สำหรับนั้นต้องใช้ไลบรารี <boost/range/adaptor/reversed.hpp>
ตัวอย่าง
#include <iostream>
#include <vector>
#include <map>
int main() {
int arr[] = { 10, 20, 30, 40, 50 };
// traditional for
for (int i = 0; i < 5; i++)
printf("%d, ", arr[i]);
printf("\n");
for (int num : arr)
printf("%d, ", num);
printf("\n");
// สำหรับ character array
char str[] = "Hello World";
for (char c : str)
printf("%c ", c);
printf("\n");
for (char c : "Hello World")
printf("%c ", c);
printf("\n");
std::map<int, char> MAP({{1, 'A'}, {2, 'B'}, {3, 'C'}});
for (auto m : MAP)
printf("{ %d, %c }", m.first, m.second);
}
ผลลัพธ์
10, 20, 30, 40, 50, 10, 20, 30, 40, 50, H e l l o W o r l d H e l l o W o r l d { 1, A }{ 2, B }{ 3, C }