Demystifying C++ - Range-Based for Loops
Jump to navigation
Jump to search
Range-based for loops in modern C++ offer a neat and intuitive way to iterate over the elements of a container or array. Compared to traditional loops where indices or iterators need to be explicitly managed, range-based for-loops offer a more concise and less error-prone syntax.
Here's the substitute code for the loop that is written in the C++17 standard:
Substitute Code | for (range-declaration : range-expression) { ... } |
auto && __range = range-expression; auto __begin = begin-expr; auto __end = end-expr; for ( ; __begin != __end; ++__begin) { range-declaration = *__begin; ... } |
---|
The following example showcases the C-code for a simple instance with `std::initializer_list`. The code follows the principle of the substitute code:
Range-based for loop
with std::initializer_list |
#include <initializer_list> void work(int); void func() { for (int i : {1, 2, 3}) { work(i); } } |
struct std::initializer_list<int> { const int *__begin_; size_t __size_; }; inline const int *std::initializer_list<int>::begin(const struct std::initializer_list<int> *this) { return this->__begin_; } inline const int *std::initializer_list<int>::end(const struct std::initializer_list<int> *this) { return this->__begin_ + this->__size_; } void work(int); void func(void) { { const int init[3] = {1, 2, 3}; struct std::initializer_list<int> tmpExpr1 = {init, 3}; struct std::initializer_list<int> *__range1 = &tmpExpr1; const int *__begin1 = std::initializer_list<int>::begin(__range1); const int *__end1 = std::initializer_list<int>::end(__range1); for (; __begin1 != __end1; ++__begin1) { int i = *__begin1; work(i); } } } |
---|
This mechanism ensures that the correct lifespan of temporary variables is maintained, preserving the intended behavior of the original C++ code when translating to C.