November 15, 2012
:-) Indeed, that is the only thing that surprised me too (but not as much as in another language, because of D's capabilities). The solution I think is this overload found in std.format of formatValue:

void formatValue(Writer, T, Char)(Writer w, auto ref T val, ref
FormatSpec!Char f)
if ((is(T == struct) || is(T == union)) && (hasToString!(T, Char) || !
isBuiltinType!T) && !is(T == enum))

-> Its body implements the generic print for structs. It either calls
the structs toString() method if available or if it is a range it uses
formatRange() otherwise it prints its type name with its contained
values.
But as you can see the templates requirement states !isBuiltinType!T, so
in case of your alias this to an int, it won't be used. So the
implementer of this method most likely had taken into account the
possibility of an alias this to a built in type.

Btw., I love D's readability, it was really easy to find this and to understand what it does.

Best regards,

Robert

On Thu, 2012-11-15 at 15:11 +0100, Joe wrote:

> I wonder though why it works at all then, because without the alias the string conversion *is* supported and produces "Property(7)".


November 16, 2012
Why would is(T == struct) be true but !isBuiltinType!T be false?
This seems highly inconsistent. If T is a struct, it is not a
builtin type, and if T is int (also making the condition false),
then Property should never have been passed as a struct, but as
the int gotten via the alias.

On Thursday, 15 November 2012 at 14:52:41 UTC, eskimo wrote:
> :-) Indeed, that is the only thing that surprised me too (but not as
> much as in another language, because of D's capabilities). The solution
> I think is this overload found in std.format of formatValue:
>
> void formatValue(Writer, T, Char)(Writer w, auto ref T val, ref
> FormatSpec!Char f)
> if ((is(T == struct) || is(T == union)) && (hasToString!(T, Char) || !
> isBuiltinType!T) && !is(T == enum))
>
> -> Its body implements the generic print for structs. It either calls
> the structs toString() method if available or if it is a range it uses
> formatRange() otherwise it prints its type name with its contained
> values.
> But as you can see the templates requirement states !isBuiltinType!T, so
> in case of your alias this to an int, it won't be used. So the
> implementer of this method most likely had taken into account the
> possibility of an alias this to a built in type.
>
> Btw., I love D's readability, it was really easy to find this and to
> understand what it does.
>
> Best regards,
>
> Robert


November 16, 2012
> Why would is(T == struct) be true but !isBuiltinType!T be false?
Exactly because of alias this. Your type is a struct and an integer at the same time, so to speak. At least it behaves that way and that's what its all about. If if looks like a duck, quacks like a duck, ... it is a duck ;-)
> This seems highly inconsistent. If T is a struct, it is not a builtin type, and if T is int (also making the condition false), then Property should never have been passed as a struct, but as the int gotten via the alias.

Your struct is both at the same time, it stops being both as soon as it is copied to a function argument expecting an int, but not any sooner. It is always passed as the struct, that's also what you are doing: You pass the struct to writefln. It only allows being treated as an int, which also means it can be copied to an int argument of a function. But this happens even later in the call chain, the above mentioned function is also a template, so it sees the struct not the naked int, but it does the expected thing because of the seemingly contradictory checks. So another overload is used, which expects builtin types.

With your alias this your struct is a struct and a builtin at the same time. Without the alias this feature, you would be right that the check makes no sense.

1 2
Next ›   Last »