On 01/10/13 13:15, monarch_dodra wrote:
By using the operator's return type, you get, basically, what the compiler
believes is the "common type" that you'd get from either a T1, or a T2.
Back to the code:
static if (is(typeof(true ? T[0].init : T[1].init) U))
This basically checks if ternary compiles, and if it does, "assigns" the return
type to U, after which, the common type becomes U.
(2) Same code -- why is it only necessary to check T[0].init : T[1].init and
not vice versa? (Yes, you can tell I don't really understand the : operator
properly:-)
Order makes no difference.
(3) What would one have to implement in a library-defined type to enable
T[0].init : T[1].init to evaluate to true?
I think you are reading the code wrong, it's not "T[0].init : T[1].init" that
evaluates to "true". It's the argument of the ternary operator. "true" is just a
dummy placeholder. What this code is checking is that "condition ? T[0].init :
T[1].init" compiles at all.
Yea, I think I had in my head "This is generic/static/compile time/template
stuff, and the only time I've ever seen A : B with respect to types is when
you're attempting to indicate that A is implicitly convertible to B."
I had a "D'oh!" moment when I realized shortly after sending the email that it
was actually probably a condition ? ifTrue : ifFalse style expression, but still
didn't get what that meant here or why it did what I did.
Now that you and others have explained this, I'm impressed. It's a very nice
example of how template code in D really is just like "real" code except that
the variables are template parameters rather than variables.
Well, given that D doesn't allow implicit construction, and that the entire
point of "CommonType" (AFAIK) is to check the *implicit* common type, it would
be a little difficult.
Ahh. OK, this makes things clear, and explain why David Simcha needed things
like CommonRational and CommonInteger in his std.rational.