There's no way for the compiler to figure out which function you're trying to call by just the return value. Since a return value does not need to be caught, you could write:
hello( 1 ); // return int
hello( 2 ); // return float
They are exactly the same call from what can be seen.
Yes that is legal since the first hi takes a reference and the second hi takes a memory address. You might call it like this:
hi( myNumber );
hi( &myNumber );
Perfectly distinguishable.