discrimination of constructors with same number of parameters

spir denis.spir at gmail.com
Thu Dec 30 06:14:05 PST 2010


On Thu, 30 Dec 2010 14:39:02 +0100
Lutger Blijdestijn <lutger.blijdestijn at gmail.com> wrote:

> 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
> }

I like very much the template mixin solution. Would there be any difference in inheriting an interface (or even a plain type)?
Also, can one presently rewrite this in D without _string_ mixin inside the template? (Else this solution is simply not acceptable for me: I'm allergic to code in strings; but don't ask me why ;-)

Denis
-- -- -- -- -- -- --
vit esse estrany ☣

spir.wikidot.com



More information about the Digitalmars-d-learn mailing list