Yes, it’s perfectly safe.
From [class.temporary]/4-5:
There are two contexts in which temporaries are destroyed at a different point than the end of the fullexpression. The first context is when a default constructor is called […]
The second context is when a reference is bound to a temporary. The temporary to which the reference is
bound or the temporary that is the complete object of a subobject to which the reference is bound persists
for the lifetime of the reference except:
- A temporary bound to a reference member in a constructor’s ctor-initializer […]
- A temporary bound to a reference parameter in a function call […]
- The lifetime of a temporary bound to the returned value in a function return statement […]
- A temporary bound to a reference in a new-initializer […]
None of those exceptions apply. The temporary thus persists for the lifetime of the reference, __range, which is the entire loop.