I am using g++ v8.2 with -std=c++2a -Wall- -Wextra -pedantic running on a Raspberry Pi 3B+. I am trying to better understand the range based for loop for my custom containers.
Below you see a class that implements a custom class with a ranged based for. That is working fine. However. I have some additional specific questions to my working implementation.
I checked already also this and others. But none of those answer my questions.
Here is the code:
#include <iostream>
struct LinkedList // Simplest linked list
{
int k;
LinkedList *next;
};
// For test pruposes: Build manually linked list as globals
LinkedList aa3{3,nullptr}; LinkedList aa2{2,&aa3}; LinkedList aa1{1,&aa2};
class Example
{
public:
Example &begin (void) { linkedList = linkedListStartAddress; return *this;}
int end (void) { return 0; }
LinkedList &operator * (void) { return *linkedList; }
void operator ++ (void) { linkedList = linkedList->next; }
bool operator != (const int&) { return (linkedList != nullptr);}
protected:
LinkedList *linkedListStartAddress {&aa1}; // Global initialisation for test purposes
LinkedList *linkedList{&aa1}; // Global initialisation for test purposes
};
int main(void)
{
Example example;
for (auto l : example)
{
std::cout << l.k << '\n';
}
return 0;
}
OK, this works.
The general definition for the loop is:
{
auto && __range = range_expression ;
auto __begin = begin_expr;
auto __end = end_expr
for (;__begin != __end; ++__begin) {
range_declaration = *__begin;
loop_statement
}
}
This is hard to understand. Neither __range, nor range_expression are used later on. 'auto' is also difficult for me in that context. I cannot see the type. Now my assumptions and questions.
- The example class is container and iterator at the same time. Is this a correct or common use case?
- Obviously the return type of 'begin' must be the type of the 'range_expression' or vice versa. Correct?
- The return type of 'begin' must be the class type, otherwise the operators (++, *, !=) would not be called. Correct?
- The 'begin' function is called just for initialisation purposes. And to return a reference to the class. It has not necessarily a relation to the underlying container. Correct?
- The 'end' function (I checked: It is called immediately after 'begin'. Then never again) has no meaning (c++17). It is just there to define (with its return value) the type for the right hand side of the 'operator !='. Correct?
- How can I deduce the type for the 'operator !=' to be a "const 'ReturnTypeOfEnd' &". I tried with decltype, but I failed.
- Obviously the return type of the 'operator*' defines the type of the range_declaration. In my case '*__begin' has a total different type than '__begin'. Not some address or something. OK?
I would be happy, if you could shed some light on this . . .