discrimination of constructors with same number of parameters

Jonathan M Davis jmdavisProg at gmx.com
Thu Dec 30 03:01:52 PST 2010


On Thursday 30 December 2010 02:50:55 spir wrote:
> Hello,
> 
> 
> When 2 constructors (*) accept the same number of parameters, the only
> remaining discrimination is type. Right? But some language types (or
> machine types) can have very diverse _human_ semantics, and thus be used
> for various purposes which should, but cannot, be considered different:
> this (int[] data, string filename) {...}
> 	this (int[] data, string message) {...}
> Aliasing like in
> 	alias string Name;
> does not help since for D Name is still string.
> 
> I know about typedef, but it is not even mentionned in TDPL, so I guess it
> is on the deprecation path. (Am I right?) So, what is the solution for
> this? (I added a 3rd fake bool parameter in one case)
> 
> Things get more complicated with unsigned integers: they can be used as
> ordinals (index, which one), as cardinals (count, how many), as any of the
> char types. These are completely different semantics for the "modeller"
> (the programmer), but for the language (thus for the machine) they are the
> same semantics.
> 
> Things get worse with template parameterisation, a case I lately met:
>     Struct S (Element) {
> 	this (int[] data, string message) {...}
> 	this (int[] data, Element element) {...}
> What happens when Element is string? Below an example:
> 
> struct S(Typ) {
>     this(int) {writeln("int");}
>     this(Typ) {writeln("Typ");}
> }
> unittest {
>     auto s1 = S!string(1);
>     auto s1 = S!int(1);
> }
> ==>
> rdmd -w -debug -unittest -L--export-dynamic --build-only -of"__trials__"
> "__trials__.d"
> 
> __trials__.d(42): Error: constructor __trials__.S!(int).S.this called with
> argument types: ((int))
> matches both:
> 	__trials__.S!(int).S.this(int _param_0)
> and:
> 	__trials__.S!(int).S.this(int _param_0)
> 
> Compilation failed.
> 
> How do you cope with such cases?
> 
> Denis
> 
> (*) or any other func, in fact, but the issue shows up more frequently on
> constructors, because they have good reasons to accept various parameter
> sets.

This is a common issue in programming languages which allow for function 
overloading. Type is what's used to determine which overload to use. If you want 
to have two overloads that use the same types, then you're out of luck. That 
generally means either creating another function or creating a new type (and 
creating a new type is generally overkill). typedef is definitely on the way out, 
so that's not a solution, and it would be a pretty fragile one IMHO anyway. So, 
what you would do normally is create another function with another name.

In the case of constructors, you can't do that. So, if you really need it, you 
create static factory methods which return a new value of that type. The factory 
methods can have different names.

But function overloading works on type. So, if two overloads would crash, you 
either have to create a new function with a new name, or you have to create a 
new type. It may be annoying sometimes, but it's still a whale of a lot better 
than not having function overloading at all - as is the case with languages such 
as C and Go.

- Jonathan M Davis


More information about the Digitalmars-d-learn mailing list