I'm exploring how reference variables work within range-based for loops in C++. While I understand that "&" typically refers to memory addresses in pointer contexts, its behavior in loops seems different.
I have two examples:
#include <iostream>
#include <string>
int main() {
std::string a = "HELLO";
for (char &x : a) {
x = tolower(x);
}
std::cout << a;
return 0;
}
#include <iostream>
#include <string>
int main() {
std::string a = "HELLO";
for (char x : a) {
x = tolower(x);
}
std::cout << a;
return 0;
}
Most resources I've found discuss range-based loops generally, but it's don't explain this reference behavior clearly. Could someone break down what's happening?
The ranged based for
-loop:
for (char &x : a) {
// ...
}
Is practically the same as this pre-C++11 loop:
for(std::string::iterator it = a.begin(), end = a.end(); it != end; ++it) {
char& x = *it; // declares a reference to an existing instance of char
// ...
}
That is, the dereferencing of the iterator, it
above, is done by the built-in range based for
loop, and the variable you bind to the result, x
, is declared as a reference, hence you can then modify what it's referencing.
Note: Make sure that you never pass a negative value to the <cctype>
functions (like std::tolower
). Always cast to an unsigned char
:
x = std::tolower(static_cast<unsigned char>(x));