if the for-range-initializer is an expression,
it is regarded as if it were surrounded by parentheses (so that a comma operator
cannot be reinterpreted as delimiting two init-declarators);
if the type of range is a reference to a
class type C, and
searches in the scope of C ([class.member.lookup])
for the names begin and end
each find at least one declaration,
begin-expr and end-expr are
range.begin() and range.end(),
respectively;
otherwise, begin-expr and end-expr are
begin(range) and end(range), respectively,
where begin and end undergo
argument-dependent lookup ([basic.lookup.argdep]).
[Example 2: using T = std::list<int>;
const T& f1(const T& t){return t; }const T& f2(T t){return t; }
T g();
void foo(){for(auto e : f1(g())){}// OK, lifetime of return value of g() extendedfor(auto e : f2(g())){}// undefined behavior} — end example]