All three calls are ambiguous, so the program won't compile.
f(3);
This could use either the first or third overload. They are equally good, so the call is ambiguous.
f(i);
This could use the first, second, or third overload. The second is better than the third; binding to int&
is preferred over binding to const int&
when it's possible. So it's fine to overload on cv-qualification in this way. But there is an ambiguity between the first and second overloads.
f(ci);
This could use the first or third overload. Again, they are equally good, so the call is ambiguous.
The standard precisely specifies the rules of overload resolution. They are very complicated, so it is a bad idea to overload functions in a way that makes it hard for the reader to tell which overload will be called. You can find the rules here.