Take this small example class (not my real code, but it exposes the problem):
Convert = class(TObject)
public
class function ToString(value: Double): String; overload;
class function ToString(value: TDateTime): String; overload;
end;
It compiles fine until you try to use the Double
or TDateTime
functions As
In:
var
d: Double;
begin
d := 99.99;
ShowMessage(Convert.ToString(d));
You will get this compile error: Ambiguous overloaded call to 'ToString'.
The problem boils down to the fact that TDateTime
is a type of Double
My Question: how do You deal with this type of problem?
EDIT - I am NOT looking for a solution for the example given
I have found 3 Solutions so far:
are there any other solutions out there?
There are two ways to resolve this ambiguity: Typecast char to float. Remove either one of the ambiguity generating functions float or double and add overloaded function with an int type parameter.
Answer: If two or more functions have the same name and function signature, the call to an overloaded function can be unclear. Explanation: Function overloading ambiguity occurs when the compiler is unable to decide which of the overloaded functions should be invoked first.
When the compiler is unable to decide which function it should invoke first among the overloaded functions, this situation is known as function overloading ambiguity. The compiler does not run the program if it shows ambiguity error.
Restrictions on overloadingAny two functions in a set of overloaded functions must have different argument lists. Overloading functions that have argument lists of the same types, based on return type alone, is an error.
Overloaded methods can be very effective. However, as soon as there is a hint of ambiguity they become a liability. A good example of this are the new TStream overloads introduced in XE3. It's not hard to fall into a trap where the compiler chooses an overload that you weren't expecting. At least in your code the compiler stopped. In that sense you were lucky.
So my advice, in your situation, is to abandon overloads. Express the different input types in the method name. Yes it's a little more verbose, but you won't make any mistakes, and you code will compile!
Your posted example compiles and executes fine in XE.
In a comment you give this example instead:
ShowMessage( Convert.ToString( 99.99 )); // <- gives compiler error 2251
In this particular case the solution is to explicitly define the type( I thought):
ShowMessage( Convert.ToString( Double(99.99) )); // <- E2089, Invalid Typecast
Looking into the documentation:
This error message is issued for type casts not allowed by the rules. The following kinds of casts are allowed:
- Ordinal or pointer type to another ordinal or pointer type
- A character, string, array of character or pchar to a string
- An ordinal, real, string or variant to a variant
- A variant to an ordinal, real, string or variant
- A variable reference to any type of the same size.
So, to explicitly tell the compiler to select the Double
overloaded function:
ShowMessage( Convert.ToString( Double(Variant(99.99)))); // Ok
A bit convoluted perhaps. But for the other overloaded function it is simpler:
ShowMessage( Convert.ToString( EncodeDate(2013,1,5));
Update
To make this a generic solution working for all classes, consider adding class functions to resolve your ambiguous types.
Convert = Class(TObject)
...
class function AsDouble( value: Double) : Double; inline; static;
class function AsTDateTime( value: TDateTime) : TDateTime; inline; static;
end;
class function Convert.AsDouble(value: Double): Double;
begin
Result := Value;
end;
class function Convert.AsDateTime(value: TDateTime): TDateTime;
begin
Result := Value;
end;
Now you can call your overloaded class function with constants:
ShowMessage( Convert.ToString( Convert.AsDouble(99.99)));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With