For an overloading method we have the method that have the same name, different number of parameters or argument but will the return type be same or not?
@jonnin so you mean the return type can be same and also can be different?
that part "the difference can't ONLY be the return type; you must also change a parameter" can you be more specific on that one?
With overload resolution, the compiler doesn't care about the return type (so these can vary), only the number and types of the parameters must be different; and if there are member functions a const member function is different to the non-const member function (the parameters can be the same).
Edit:
The above is just a basic conceptual view, other complications are here:
and as to the above, if you had that and called it with a char or short, some compilers will complain because those types have an implicit conversion to both double and int, and you end up needing something like this to call it:
foo( (int)(variable));
the built in numeric types can be a little frustrating with overloads.
I wonder which compiler you had that did this, I would have thought that integral promotion beats floating-point conversion.* I tested it on godbolt with g++ 11.2 and clang 13.0 with std=c++20: the int version was called each time with char or short as the argument type. I am sure it has happened to you, otherwise you wouldn't have mentioned it :+).
Maybe I am interpreting it wrong, there is a lot of documentation there. Or maybe it was a bug that was consequently fixed?
The argument-parameter implicit conversion sequences considered by overload resolution correspond to implicit conversions used in copy initialization (for non-reference parameters), except that when considering conversion to the implicit object parameter or to the left-hand side of assignment operator, conversions that create temporary objects are not considered.
Each type of standard conversion sequence is assigned one of three ranks:
1) Exact match: no conversion required, lvalue-to-rvalue conversion, qualification conversion, function pointer conversion, (since C++17) user-defined conversion of class type to the same class
2) Promotion: integral promotion, floating-point promotion
3) Conversion: integral conversion, floating-point conversion, floating-integral conversion, pointer conversion, pointer-to-member conversion, boolean conversion, user-defined conversion of a derived class to its base
I may have given a bad example. I remember tripping over this at one point and getting one of those errors "overload is ambiguous", and likely enough I simply did something wrong (I remember fixing it via a cast on the call side, though), but I am not sure I can reproduce it now. If I get a chance I will see if I can break it again.
Indeed an annoyance. Perhaps it is a shame that all the conversions have the same rank; more logical In My Mind (IMM) that conversions within one value type (floating point: float, double, long double) would beat conversion to another value type (Integral)
At least it may alert one to think of a narrowing conversion, I tend to do this a lot, to force the issue:
I've encountered very similar ambiguities in practice and it's often a case where the type system has caught an unintentional type conversion.
90% of the floating point code I write is single-precision. I've found it a relatively common error to "poison" single-precision computations with an operand of type double, because a preference for double is designed into the language. So some expression might produce double where you wanted float, and the conversion back from double back to float causes subtle issues.
At least it may alert one to think of a narrowing conversion, I tend to do this a lot, to force the issue:
That would have saved me. If you control the interface perhaps a judicious application of delete works too: void foo(double) = delete;
Overall I think implicit conversions are allowed too frequently.