Yes, but there are more rules (lots of them)...
The compiler also does an Unqualified name lookup
https://en.cppreference.com/w/cpp/language/unqualified_lookup
(about 10 pages of rules) for "<< *ls.begin" and finds the global one
from main(), because the call is done from the global namespace.
The code for std::copy is inside namespace std so the search for an
operator starts there. And it finds lots of operator<< in the namespace,
so it stops there:
"For an unqualified name, that is a name that does not appear to the
right of a scope resolution operator ::, name lookup examines the scopes
as described below, until it finds at least one declaration of any kind,
at which time the lookup stops and no further scopes are examined."
And then the compiler performs an overload resolution (another 30 pages
in the standard) for the names it has found.
The complete process is *way* too complicated to fully describe in a
post here, so the recommendation is to always declare the operators in
the same namespace as (at least one of) the operands, and avoid most of
the complications.
Bo Persson