In Delphi, I can do this:
Type
TFourCC = Array[0..3] of AnsiChar;
Function Func(Param : TFourCC) : Boolean;
begin
{ ... }
end;
Func('ABCD'); // I can pass this as literal text without problems
Now, I want to make this parameter optional.
Function Func(Param : TFourCC = 'ABCD') : Boolean;
begin
{ ... }
end;
Now, the compiler throws me an error: E2268 Parameters of this type cannot have default values
Ok, so I was thinking overloading the function should do the trick then...
Function Func : Boolean; overload;
begin
{ ... }
end;
Function Func(Param : TFourCC) : Boolean; overload;
begin
{ ... }
end;
Func('ABCD'); // This line that worked in first example now gives an error
Unfortunately, Delphi doesn't like this either. Where it first accepted the parameter as a TFourCC
typed variable, it now gives me E2250 There is no overloaded version of 'Func' that can be called with these arguments
.
I beg to disagree with what this error tells me, the same thing worked when it wasn't overloaded.
Can someone explain me the logic behind this, and possibly a solution? I'd like to keep the TFourCC
as it is (not a string type), it keeps the handling of reading and writing much easier. I rather avoid assigning it to a variable first before passing it, because the function will be used alot..
A whole array cannot be passed as an argument to a function in C++. You can, however, pass a pointer to an array without an index by specifying the array's name.
2) Member function declarations with the same name and the name parameter-type-list cannot be overloaded if any of them is a static member function declaration.
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.
The return type of a function has no effect on function overloading, therefore the same function signature with different return type will not be overloaded. Example: if there are two functions: int sum() and float sum(), these two will generate a compile-time error as function overloading is not possible here.
Unfortunately, this is how the type system currently works.
But the good news is that you can do magic with records and operator overloading. For instance, with
type
TFourCC = record
strict private
function GetChar(Index: Integer): AnsiChar;
procedure SetChar(Index: Integer; const Value: AnsiChar);
public
class operator Implicit(AValue: AnsiString): TFourCC;
class operator Implicit(AValue: TFourCC): AnsiString;
class operator Equal(a, b: TFourCC): Boolean;
class operator NotEqual(a, b: TFourCC): Boolean;
property Chars[Index: Integer]: AnsiChar read GetChar write SetChar; default;
case Boolean of
False: (AnsiChars: array[0..3] of AnsiChar);
True: (Data: Cardinal)
end;
implementation
{ TFourCC }
class operator TFourCC.Implicit(AValue: AnsiString): TFourCC;
begin
if Length(AValue) <> 4 then
raise Exception.Create('Not a valid TFourCC string.');
Result.Data := PCardinal(@AValue[1])^;
end;
class operator TFourCC.Implicit(AValue: TFourCC): AnsiString;
begin
SetLength(Result, 4);
PCardinal(@Result[1])^ := AValue.Data;
end;
class operator TFourCC.Equal(a, b: TFourCC): Boolean;
begin
Result := a.Data = b.Data;
end;
class operator TFourCC.NotEqual(a, b: TFourCC): Boolean;
begin
Result := a.Data <> b.Data;
end;
function TFourCC.GetChar(Index: Integer): AnsiChar;
begin
Result := AnsiChars[Index];
end;
procedure TFourCC.SetChar(Index: Integer; const Value: AnsiChar);
begin
AnsiChars[Index] := Value;
end;
you get all these benefits:
procedure TForm1.FormCreate(Sender: TObject);
var
x: TFourCC;
begin
x := 'FINE'; // implicit conversion from string
ShowMessage(x); // implicit conversion to string
x[0] := 'D'; // can access parts for writing (without explicit member)
ShowMessage(x);
ShowMessage(x[0]); // can access parts for reading (without explicit member)
ShowMessage(x.Data.ToString); // can access underlying storage as a 32-bit integer
end;
And, you can now do
procedure f(A: TFourCC); overload;
begin
ShowMessage(A);
end;
procedure f; overload;
begin
ShowMessage('ABCD');
end;
Unfortunately, I am very much in a hurry right now, so I cannot double-check the correctness or comment further right now!
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