First, don't use using namespace std;. In this case, there happens to be a struct called std::plus—oh, wait, never mind, that's actually called plus and its constructor is thrown into the bucket for overload resolution with your function called plus.
Second, you have an ambiguity because 3.2 and 4.2 are of type double and can convert equally well to float or int.
This is a simplification, but when it comes to passing numbers to an overloaded function, C++ basically uses these rules:
- If all the arguments exactly match one of the overloads, then use that one.
- If all the arguments can be promoted to match one of the overloads, then use that one.
- If all the arguments can be numerically converted to match one of the overloads, then use that one.
If you have multiple candidates at a specific level, then that is an ambiguity. Crucially, a double does not promote to a float—that would be a downgrade. So it has to use a standard conversion to a float, which ties with the standard conversion to an int, so those two overloads are ambiguous.