is() syntax (Re: operator new(): struct v. class)

Bill Baxter dnewsgroup at billbaxter.com
Mon Aug 20 17:49:31 PDT 2007


Kirk McDonald wrote:
> C. Dunn wrote:
>> Kirk McDonald Wrote:
>>
>>
>>>> But Walter, how did you handle operator new()?  It needs to be 
>>>> agnostic about class/struct.
>>>>
>>>> class C{int x;};
>>>> stuct S{int x;};
>>>> typedef C MyType;
>>>> //typedef S* MyType;
>>>> MyType inst = new MyType;
>>>>
>>>> If you use the second typedef, this will not compile!  That is the 
>>>> problem.
>>>>
>>>> Why not provide an operator New() which expects a pointer type when 
>>>> used for structs?  Just have the compiler translate it.  I cannot 
>>>> see how to write such a generic operator New() myself.
>>>>
>>>
>>> It's a trivial bit of template code. Something like this:
>>>
>>> T New(T)() {
>>>     static if (is(T U == U*)) {
>>>         return new U;
>>>     } else {
>>>         return new T;
>>>     }
>>> }
>>>
>>> class C {}
>>> struct S {}
>>>
>>> void main() {
>>>     C c = New!(C);
>>>     S* s = New!(S*);
>>> }
>>
>>
>> I don't understand your static if expression.  Where in the docs is 
>> there an explanation for "is(T U == U*)"?  I completely missed that, 
>> and I really do not understand what it does.
>>
> 
> It's the IsExpression:
> 
> http://www.digitalmars.com/d/expression.html#IsExpression
> 
> Specifically, it's this form of the IsExpression:
> 
> is ( Type Identifier == TypeSpecialization )
> 
> "The condition is satisfied if Type is semantically correct and is the 
> same as TypeSpecialization. The Identifier is declared to be either an 
> alias of the TypeSpecialization or, if TypeSpecialization is dependent 
> on Identifier, the deduced type."
> 
> That is, if T can be expressed as U*, is() evaluates to true, and U is 
> declared to be an alias to the appropriate type.

Which I think is a top contender in the running for the weirdest syntax 
ever devised for a construct in a C-derived language.

It's basically an is(Type==TypeSpecialization) that includes type 
deduction.  You're not comparing Identifier with TypeSpecialization so 
it's bizarre to write anything that looks like U==U*.  Obviously U is 
not U* for any value of U.  Any of the following would look more 
sensible if you ask me:

either put the Identifier first
   is(U : Type == U*)
   is(U ; Type == U*)
   is(U | Type == U*)
   is(U <- Type == U*)
or put it last
   is(Type == U*  U)
   is(Type == U* : U)
   is(Type == U* | U)
   is(Type == U* -> U)
   is(Type == U* with U)
or use template syntax
   is!(U)(Type==U*)

And why do we even need is() to do basic type comparisons anyway?
What's ambiguous about
    static if( MyType == OtherType ) {
         ...
    }
?
I guess you could define a static opEquals, but A) that's useless enough 
that it could be outlawed B) it wouldn't take a type as an argument so 
it still wouldn't be ambiguous.

--bb



More information about the Digitalmars-d mailing list