The declarations of foo3 and foo4 are legal because the argument to those functions is not a reference.
The declaration of foo2 is illegal because you can't bind a non-const reference to a temporary.
So why is the declaration of foo1 legal? It's that very important const qualifier that makes this declaration legal.