8

just a question, i have:

myclass = class
public
  function Funct1: String;
  function Funct2: Integer;
end;

It turn me error, so i have tried with:

myclass = class
public
  function Funct1: String; overload;
  function Funct2: Integer; overload;
end;

but same problem; delphi tell me that has same parameter. Now, i ask, is possible to do in mode to have more function with same name but with different output as in example? Thanks very much for help.

UPDATE

Sorry, i done a error, not funct1 and funct2, but both funct1, so:

myclass = class
public
  function Funct1: String; overload;
  function Funct1: Integer; overload;
end;

Doing so, compiler return me this error:

[DCC Error] Project1.dpr(15): E2252 Method 'funct1' with identical parameters already exists [DCC Error] Project1.dpr(22): E2037 Declaration of 'funct1' differs from previous declaration

Of course, i know becouse give error and need change name to one of both function (for it me confused before) but i wanted know if there was some trick or other solution for to have a situation as this without error. Thanks again.

Jens Mühlenhoff
  • 14,565
  • 6
  • 56
  • 113
Marcello Impastato
  • 2,263
  • 5
  • 30
  • 52
  • 1
    In principle the compiler could do what you want, in some situations. Your example of string and integer would be trivial to handle. But that feature is not implemented. – David Heffernan Sep 15 '11 at 11:15
  • IMO, what you are trying to accomplish is not going to be useful, will make your code harder to maintain, and seems contrary to common sense. – Chris Thornton Sep 15 '11 at 12:33
  • Related question: http://stackoverflow.com/questions/2124841/is-there-a-way-to-overload-a-function-based-on-different-result-type-in-delphi – Jens Mühlenhoff Sep 15 '11 at 14:11

5 Answers5

14

You could turn the function into a procedure taking a var parameter:

myclass = class
public
  procedure Funct1(var AResult: String); overload;
  procedure Funct1(var AResult: Integer); overload;
end;
Uli Gerhardt
  • 13,748
  • 1
  • 45
  • 83
13

What you post doesn't make sense. The first example should compile without any problem, as the functions have different names, Funct1 and Funct2.

Problems only arise when methods (or functions) have the same name. Then, normally, an overload directive would be in order, but overload can't distinguish functions on return value alone.

So assuming the names are the same, what you want is impossible. There is no way to overload these functions, if they don't have a different parameter signature. You can just give them different names, which is preferrable anyway, as they apparently do different things.


FWIW, your question is flawed by the fact that you apparently did not post the exact code with which you are actually having problems. Please always post the exact code that causes your problems, and if there are error messages, always post the exact error message (they can usually be copied using the usual copy keystrokes, e.g. Ctrl+C, even in most parts of the IDE or in message dialogs in Delphi). If there are any line numbers in the error message, indicate this in the source code you post, as we don't always have the same line numbers as you have.

Rudy Velthuis
  • 28,387
  • 5
  • 46
  • 94
12

Firstly, for functions to be overloaded, they have to be named the same.

Secondly, this is not possible to do. Overloaded functions must have different parameters.

In your case, there is no way the compiler can tell which of your functions to call (assumed that both are renamed to Funct1):

var
  v: Variant;
  mc: myclass;
begin
  v := mc.Funct1;
end;
gabr
  • 26,580
  • 9
  • 75
  • 141
6

if you want to overload methods with different return types, just add a dummy parameter with default value to allow the overload execution, but don't forget the parameter type should be different so the overload logic works e.g:

type    
    myclass = class
    public
      function Funct1(dummy: string = EmptyStr): String; overload;
      function Funct1(dummy: Integer = -1): Integer; overload;
    end;

use it like this

procedure tester;
var yourobject : myclass;
  iValue: integer;
  sValue: string;
begin
  yourobject:= myclass.create;
  iValue:= yourobject.Funct1(); //this will call the func with integer result
  sValue:= yourobject.Funct1(); //this will call the func with string result
end;

also don't forget that this way your gonna have a problem with variants like in this example:

procedure tester;
var yourobject : myclass;
  vValue: variant;
begin
  yourobject:= myclass.create;
  vValue:= yourobject.Funct1(); 
end;

until you implement the variant function too:

      function Funct1(dummy: Variant = Unassigned): Variant; overload;
ZORRO_BLANCO
  • 849
  • 13
  • 25
  • 2
    It is clever what are you doing, however fooling a compiler was never the wise to do – Nasreddine Galfout Mar 31 '19 at 17:40
  • 2
    Thanks, I think...And about the compiler fooling issue it actually comes from the question it self ! because what we are trying to do from the beginning is to overload a function based on the result type and that means fooling the compiler,so this is how you can understand the question "how can i fool the compiler to overload a function based on the result type?", what am saying is that this question deserves this answer, otherwise i just used the strategy pattern from the behavioral design patterns..and this is used almost every where including the VCL – ZORRO_BLANCO Apr 02 '19 at 12:56
  • At first I thought it was a nice hack. but `vValue:= yourobject.Funct1()` won't compile in Delphi 5. with Error: `Ambiguous overloaded call to 'Funct1'`. Maybe this compiles in newer versions. I can't confirm right now. – kobik Jun 11 '19 at 11:12
  • @kobik I confirm it works on Delphi 7 and later versions – ZORRO_BLANCO Sep 24 '19 at 07:26
  • I try your code in `RAD Studio 11.3` and it fail with `E2251 Ambiguous overloaded call to 'Funct1'` – Chau Chee Yang Apr 14 '23 at 13:33
3

As was already stated, you cannot do it as you are wanting to do. However, you could just as easily implement each function with a different name such as "AsInteger" or "AsString". Your code will be clearer and this is generally the way it is done within the VCL.

TmyClass = class (TObject)
public
  function AsString : string;
  function AsInteger : Integer;
end;
Jerry Gagnon
  • 1,131
  • 8
  • 16
  • That depends on the result being different representations of the sáme value. – NGLN Sep 15 '11 at 16:42
  • 1
    True, but the original question was about overloading them, which in my mind would mean they are all related (since they have no parameters then their results must be related). In any event, name the functions according to the meaning of their result and all is fine. – Jerry Gagnon Sep 15 '11 at 16:55