Iteration Simplification with Custom Types
In C 11, the introduction of range-based for loops has simplified the process of iterating over sequences. These loops follow a standardized pattern:
for (Type& v : a) { ... } // equivalent to traditional loop below
for (auto iv = begin(a); iv != end(a); ++iv) {
Type& v = *iv;
...
}
Copy after login
You can extend this functionality to your custom types, allowing them to be used in range-based loops, by following these guidelines:
Approach 1: Member Function Declaration
- Define begin() and end() member functions in your type X that return objects with iterator-like behavior.
Approach 2: Free Function Invocation
- Create free functions begin(X&) and end(X&) in the same namespace as your type X, again returning iterator-like objects.
These functions will provide the necessary initialization (begin()) and termination (end()) points for the range-based loop.
Function Return Value Requirements
The objects returned by begin() and end() do not need to be actual iterators. They must, however, meet the following requirements:
- Overload pre- to increment the object
- Ensure valid initialization expressions
- Support binary != for boolean context
- Implement unary * to return a value assignable to the loop variable
- Provide a public destructor
Additional Considerations
- If your custom type belongs to the xml namespace, define xml::begin() to avoid potential conflicts with std::begin().
- Future C revisions may decouple the types of begin() and end(), allowing for "lazy-end" evaluation.
- C 17 introduced a new type, null_sentinal_t, which facilitates range-based loops over null-terminated character buffers.
- The range-based loop uses temporary variables stored in auto&& references, which means your begin() and end() overloads cannot detect if they are operating on temporaries.
The above is the detailed content of How Can I Make My Custom C Types Iterable Using Range-Based For Loops?. For more information, please follow other related articles on the PHP Chinese website!