discrimination of constructors with same number of parameters

Lutger Blijdestijn lutger.blijdestijn at gmail.com
Thu Dec 30 05:39:02 PST 2010


Guilherme Vieira wrote:

> On Thu, Dec 30, 2010 at 9:24 AM, bearophile
> <bearophileHUGS at lycos.com>wrote:
> 
>> Jonathan M Davis:
>>
>> > typedef is definitely on the way out, so that's not a solution,
>>
>> typedef is deprecated (because its semantics is not flexible enough and
>> because it doesn't play well with object oriented language features), but
>> I have a real need for something like it. Andrei has discussed about a
>> Phobos-based typedef replacement (based on structs + alias this), but
>> nothing concrete has come out yet. I hope to see something to solve
>> problems like spir ones.
>>
>>
>> > and it would be a pretty fragile one IMHO anyway.
>>
>> Please, explain better.
>>
>> Bye,
>> bearophile
>>
> 
> As far as I know, typedef was a form of "discriminated alias". I don't
> know the reasons for its deprecation. It just occurred to me that D's
> typedefs + templates could be quite handy in this case.
> 
> Consider:
> 
> struct semantic_wrapper(T)
> {
>     this(T value) { this.value = value; }
> 
>     T value;
> }
> 
> typedef semantic_wrapper!(int) Position;
> typedef semantic_wrapper!(size_t) Count;
> typedef semantic_wrapper!(string) Filename;
> typedef semantic_wrapper!(string) DirPath;
> 
> void func(Position pos) { ... }
> void func(Count c) { ... }
> void func(Filename fname) { ... }
> void func(DirPath dir) { ... }
> 
> void main()
> {
>     func(Position(1)); // calls first overload
>     func(Count(5)); // calls second
>     func(Filename("file.txt")); // third
>     func(DirPath("/dev/null")); // fourth
> 
>     func(1); // fails
>     func("blah"); // fails
> }
> 
> 
> Requires a little more typing, but sometimes it can be better than
> creating a new function name (which can get extra-big, non-telling or
> both) or than creating factory methods (which I personally dislike,
> although it's just a matter of taste most of the time; sometimes you may
> want to instantiate from inside a template and classes needing factories
> would not work, for example, but one could argue on the validity of this
> anytime).
> 
> Just giving my 2 cents. Dunno if I missed some detail.
> 

Here is an attempt to implement it, still needs support for writeln and 
lacks some details:

import std.stdio;

mixin template Newtype(T, string typename)
{
    mixin("struct " ~ typename ~ " { alias base this; " ~ T.stringof ~
          " base;  @disable void opAssign(" ~ T.stringof ~ ") {} }");
}

mixin Newtype!(int, "Position");
mixin Newtype!(size_t, "Count");
mixin Newtype!(string, "FileName");
mixin Newtype!(string, "DirPath");

void func(Position pos) { writeln("position: ", pos.base ); }
void func(Count c) { writeln("count:", c.base); }
void func(FileName fname) { writeln("filename:", fname.base); }
void func(DirPath dir) { writeln("dirpath:", dir.base); }

void func2(int pos) { writeln("position: ", pos); }

void main()
{
  
    func(Position(1)); // calls first overload
    func2(Position(1)); // implicit conversion to int with alias this
    func(Count(5)); // calls second
    func(FileName("file.txt")); // third
    func(DirPath("/dev/null")); // fourth
    func(1); // fails
    func("blah"); // fails

    auto p = Position(1);
    p = 2; // fails
    p.base = 4; // ok, explicit
}


More information about the Digitalmars-d-learn mailing list