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