typedef
Denis Koroskin
2korden at gmail.com
Fri Mar 6 10:02:51 PST 2009
On Fri, 06 Mar 2009 20:47:40 +0300, Andrei Alexandrescu <SeeWebsiteForEmail at erdani.org> wrote:
> I tried typedef in two instances, to sadly conclude that it's not useful
> as a true abstraction mechanism. The good news is that it's very close
> to being useful.
>
> Ideally, typedef should provide a completely parallel type with the type
> under the typedef, as if you sat down and wrote it from scratch.
> Unfortunately, today typedef is just about equivariant with the type it
> comes from:
>
> void main()
> {
> typedef int IDType;
> IDType id = 5;
> int x = id;
> }
>
> This compiles and runs flag-free. An IDType accepts any int without any
> fuss, and furthermore an int accepts an IDType no problem. As such,
> typedef introduces neither a supertype nor a subtype of int.
>
> I believe this behavior is unhelpful as it prevents IDType from being a
> true abstraction mechanism. What should happen is that only this should
> compile:
>
> void main()
> {
> typedef int IDType;
> auto id = IDType(5);
> int x = id;
> }
>
> So the literals of type IDType have the form IDType(n). That way it's
> visible that we want to deal in IDType objects. I think it's ok that the
> int can be be teased out of an IDType without an explicit conversion.
> Requiring a cast would be a tad too rigid. So with the new rules in
> place we defined a sort of subtype of int.
>
> This works even better with classes. Consider exceptions for instance:
>
> typedef Exception MyException;
>
> void main()
> {
> try
> {
> throw new MyException("x");
> }
> catch(MyException e) { writeln("a"); }
> catch (Exception e) { writeln("b"); }
> }
>
> This code doesn't compile with:
>
> Error: catch at ./test.d(19) hides catch at ./test.d(20)
>
> So to the compiler typedefs are today too much the same as the source
> type.
>
>
> Andrei
It seems that typedef defined a some kind of sub-type:
class Foo {};
typedef Foo Bar; // a
//class Bar : Foo {} // b
void main()
{
Bar bar;
Foo foo;
foo = bar; // fine
bar = foo; // error
}
<OT>
Note that I get different error messages in cases a and b:
a - Error: cannot implicitly convert expression (foo) of type test.Foo to Bar
b - Error: cannot implicitly convert expression (foo) of type test.Foo to test.Bar
Is it a bug? Shoudn't the two report the same error (i.e. "test.Bar")? Does it affect mangling?
</OT>
It works the same for built-in types:
alias int Foo;
typedef Foo Bar;
void main()
{
Bar bar;
Foo foo;
foo = bar; // fine
bar = foo; // error
}
Looks sensible and consistent to me.
More information about the Digitalmars-d
mailing list