C++: Argument-dependent name lookup

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.