3

I have an example class with two class functions Foo. One takes an argument, the other doesn't:

TContoso = class
   class function Foo: IUnknown; overload;
   class function Foo(bar: IUnknown): IUnknown; overload;
end;

And i can call my static function without incident:

unk := TContoso.Foo;

But if the methods were named what i wanted to call them in the first place:

TContoso = class
   class function Create: IUnknown; overload;
   class function Create(bar: IUnknown): IUnknown; overload;
end;

Then the same class method call:

unk := TContoso.Create;

fails to compile:

Ambiguous overload call to 'Create'

Why is the non-ambiguous call ambigious? I hope it's not an arbitrary thing.

Why would you do that?

Not that it matters to the question, but if we ignore the question and focus on the situation i'm in, some would recognize the pattern:

CoXmlWriter = class
   class function Create: IXmlWriter; overload;
   class function Create(const stream: ISequentialStream): IXmlWriter; overload;
end;
Ian Boyd
  • 246,734
  • 253
  • 869
  • 1,219
  • Could you make stream an optional parameter and drop it down to one Create function? – alcalde Mar 02 '14 at 00:04
  • @alcalde I could do a lot of things. Although don't confuse the question with the example. In reality i have four creates `Create()`, `Create(IStream)`, `Create(ISequentialStream)`, `Create(filename)`, `Create(TStream)`. – Ian Boyd Mar 02 '14 at 01:19
  • I wonder why you call a class function Create. Maybe making these constructors is a way around the problem. – David Heffernan Mar 02 '14 at 09:22
  • Just following the pattern the other 768 Co classes inside the VCL and Delphi's code generator. In the end I gave up, and heroes the compiler resolve the ambiguous calls by giving then unique names (Create, CreateWithFoo, CreateWithBar, CreateWithBah) – Ian Boyd Mar 02 '14 at 12:08

2 Answers2

2

I believe that the ambiguity is with the constructor declared in TObject that has identical parameters.

However, in modern versions of Delphi the code compiles. And I think that is right because the TObject constructor is not marked with overload. So this feels like a Delphi 5 compiler bug.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • 1
    Oh god, now i remember. [Once you introduce an `overload`, the ancestor constructors leak in](http://wiert.me/2010/11/02/interesting-delphi-questions-on-stackoverflow-by-ian-boyd-in-constructors-methods-and-directives/). – Ian Boyd Mar 01 '14 at 18:50
1

Try this:

Contoso = class
   class function Create: IUnknown; overload; reintroduce;
   class function Create(bar: IUnknown): IUnknown; overload;
end;

(or perhaps switch around overload; and reintroduce; modifiers)

HeartWare
  • 7,464
  • 2
  • 26
  • 30
  • Yeah, nothing can fix it. i had a [series of questions a few years ago](http://wiert.me/2010/11/02/interesting-delphi-questions-on-stackoverflow-by-ian-boyd-in-constructors-methods-and-directives/). It's just a fundamental limitation of the compiler. – Ian Boyd Mar 01 '14 at 23:13