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