In this context, where the type is deduced, the `&&` makes that type a
“universal reference” , also known as a “forwarding reference”.
In effect, if `i` is bound to an rvalue expression (a temporary), then
type deduction plus the rules for collapsing of `&`-sequences make `i`
of type `T&&`, an rvalue reference. And if `i` is bound to an lvalue
expression, then those same rules make `i` of type `T&`, an ordinary
C++03 reference. This is the sort of shape shifting nature of a
universal reference.
For this particular case `i` is bound to an lvalue in each iteration of
the loop, and thus its type is `T&`, namely `std::string&`.
If the programmer was well aware of things and wrote that intentionally,
not just blindly copying what he/she had seen elsewhere, then the only
purpose I can think of would be to support a later modification of the
code where `i` might instead be bound to an rvalue.
In that case the reference makes the code compile and avoids copying the
value (in each iteration).
Cheers & hth.,
- Alf