Q:

How to determine which overloaded function is called?

#include <iostream>
#include <cmath>
using namespace std;

float f (int a, int b) {
    return (a + b);
}

float f (float a, float b) {
    return (round(a + b));
}

int main ()
{
    cout << "Hello World!" << endl;
    int int1 = 1;
    int int2 = 2;
    float float1 = 1.2f;
    float float2 = 1.4f;
    cout << f(int1, int2) << endl;     // output: 3
    cout << f(float1, float2) << endl; // output: 2
    cout << f(int1, float2) << endl;   // output: 2
    return 0;
}

Why the last output uses the second definition of f? 
In general, how to determine which overloaded function definition will be used, when there is not an exact matching of the number and types of the arguments between the function definitions and the function call?

A:

After trying to determine in the standard why should one overload preferred over the other I have come to the conclusion that it shouldn't, no overload has a better conversion sequence than the other in the case of f( int1, float2 ) and the code should not compile. If your compiler is accepting it, there might be a bug in the implementation.
As of the second question, the standard defines the conversions that can be used to match a call to a function and it also defines a rank for those conversions that serves as a partial ordering (called better conversion than). The compiler will always choose the best conversion, and if there is no best conversion then the program is ill formed as in the example.
Verification of the ambiguity of the code with different compilers:
GCC:
conv.cpp:22: error: call of overloaded ‘f(int&, float&)’ is ambiguous
conv.cpp:5: note: candidates are: float f(int, int)
conv.cpp:9: note:                 float f(float, float)

clang:
conv.cpp:22:13: error: call to 'f' is ambiguous
    cout << f(int1, float2) << endl;   // output: 2
            ^
conv.cpp:5:7: note: candidate function
float f (int a, int b) {
      ^
conv.cpp:9:7: note: candidate function
float f (float a, float b) {
      ^

MSVS 2010 (Thanks to Xeo):
error C2666: 'f' : 2 overloads have similar conversions
          src\main.cpp(2): could be 'void f(int,int)'
          src\main.cpp(1): or       'void f(float,float)'
          while trying to match the argument list '(int, float)'

