Why it is legal here to create lvalue reference to prvalue?
c++, c++11, language-lawyer
Solution
The range-based `for` loop is most definitely not macro expansion. It's a separate construct of the language. Still, while the vector itself is a prvalue, its member functions still operate normally. So its `operator[]` (or dereferencing its iterator) returns a normal lvalue reference etc.
Of course, such references are only valid as long as the vector itself exists. Its lifetime lasts for the entire range-based `for` loop (that is mandated by the range-based `for` loop specification in the standard), so all is well.
As far as value categories are concerned, it's the same as this (which is also legal):
int &i = std::vector<int>{1, 2, 3}[0];
Of course, unlike the one in the range-based `for` loop, this `i` reference become dangling immediately. But the principle is the same.
Consider also this: the language has no way of knowing that the lvalue reference returned by the iterator's `operator *` or the vector's `operator[]` refers to something whose lifetime is bound to that of the vector. It simply returns an lvalue reference, so it's bindable.
Problem
I have code below: ``` #include <vector> #include <iostream> int main(){ for(int& v : std::vector<int>{1,3,5,10}) { std::cout << v << std::endl; v++; // Does this cause undefined behavior? } return 0; } ``` As far as I understand, the vector is prvalue, and cannot bind to `int&`, but this one works correctly? Is it because for range loop is simply macro expansion and a temporary variable would be created for the vector?