Sometimes C++ still surprises me. Consider this code:

namespace ns1
{
  class C1
  {
  };

  void f1(const C1&)
  {
  }
}


int main()
{
  ns1::C1 c1;
  f1(c1);

  return 0;
}

If you think it's wrong and causes a compiler error, you're wrong.

The function "f1" is not in the scope of "main", but its argument has a type of the same namespace, causing the function to be located.

This rule is called Argument-dependent name lookup (or Koenig lookup) and it is also very necessary in relation to operators.