Thread overview
Detecting if a class type (which may or may not have a default constructor) is abstract
Nov 13, 2008
BCS
Nov 14, 2008
Christopher Wright
Nov 14, 2008
Max Samukha
November 13, 2008
I just don't think it's possible.  If all classes had default ctors, it'd be easy; is(typeof(new T)) would be false if and only if T were abstract.  But since that's not the case, I can't think of a way to generically see if a given class type is abstract.  Any ideas?

It's always a little frustrating when doing type introspection and having to rely on weird side-effects and properties of types, when the compiler is just keeping it in some flag or field somewhere.  Sigh. "is(T == abstract)"?  :P
November 13, 2008
Reply to Jarrett,

> I just don't think it's possible.  If all classes had default ctors,
> it'd be easy; is(typeof(new T)) would be false if and only if T were
> abstract.  But since that's not the case, I can't think of a way to
> generically see if a given class type is abstract.  Any ideas?
> 
> It's always a little frustrating when doing type introspection and
> having to rely on weird side-effects and properties of types, when the
> compiler is just keeping it in some flag or field somewhere.  Sigh.
> "is(T == abstract)"?  :P
> 

_traits(isAbstractClass, Class) // 2.0 only IIRC


November 14, 2008
On Thu, Nov 13, 2008 at 5:26 PM, BCS <ao@pathlink.com> wrote:
> Reply to Jarrett,
>
>> I just don't think it's possible.  If all classes had default ctors, it'd be easy; is(typeof(new T)) would be false if and only if T were abstract.  But since that's not the case, I can't think of a way to generically see if a given class type is abstract.  Any ideas?
>>
>> It's always a little frustrating when doing type introspection and having to rely on weird side-effects and properties of types, when the compiler is just keeping it in some flag or field somewhere.  Sigh. "is(T == abstract)"?  :P
>>
>
> _traits(isAbstractClass, Class) // 2.0 only IIRC

D1.
November 14, 2008
Jarrett Billingsley wrote:
> I just don't think it's possible.  If all classes had default ctors,
> it'd be easy; is(typeof(new T)) would be false if and only if T were
> abstract.  But since that's not the case, I can't think of a way to
> generically see if a given class type is abstract.  Any ideas?
> 
> It's always a little frustrating when doing type introspection and
> having to rely on weird side-effects and properties of types, when the
> compiler is just keeping it in some flag or field somewhere.  Sigh.
> "is(T == abstract)"?  :P

If you know the constructor arguments in advance, you can do something like:
static if (is (typeof (new Foo (1, "hello")))){}

Unfortunately, ParameterTupleOf!(T._ctor) doesn't work:

class AFoo {}
if (is (typeof (AFoo._ctor))) Stdout.formatln ("AFoo._ctor");
if (is (typeof (ParameterTupleOf!(AFoo._ctor)))) Stdout.formatln ("AFoo._ctor params");
// prints AFoo._ctor

_ctor is a really odd construct -- spotty support, not advertised.
November 14, 2008
On Thu, Nov 13, 2008 at 8:50 PM, Christopher Wright <dhasenan@gmail.com> wrote:
> Jarrett Billingsley wrote:
>>
>> I just don't think it's possible.  If all classes had default ctors, it'd be easy; is(typeof(new T)) would be false if and only if T were abstract.  But since that's not the case, I can't think of a way to generically see if a given class type is abstract.  Any ideas?
>>
>> It's always a little frustrating when doing type introspection and having to rely on weird side-effects and properties of types, when the compiler is just keeping it in some flag or field somewhere.  Sigh. "is(T == abstract)"?  :P
>
> If you know the constructor arguments in advance, you can do something like:
> static if (is (typeof (new Foo (1, "hello")))){}

Oh, definitely.  But I'm writing a library where the ctor signatures are provided by the user, and "new T(InitsOf!(Types))" could fail either because T is abstract or because they just gave an invalid signature

> Unfortunately, ParameterTupleOf!(T._ctor) doesn't work:
>
> class AFoo {}
> if (is (typeof (AFoo._ctor))) Stdout.formatln ("AFoo._ctor");
> if (is (typeof (ParameterTupleOf!(AFoo._ctor)))) Stdout.formatln
> ("AFoo._ctor params");
> // prints AFoo._ctor
>
> _ctor is a really odd construct -- spotty support, not advertised.

I wish it worked right.  Constructors are always the odd ones out. They're just functions, and should be introspectable as such.
November 14, 2008
On Thu, 13 Nov 2008 21:07:03 -0500, "Jarrett Billingsley" <jarrett.billingsley@gmail.com> wrote:

>On Thu, Nov 13, 2008 at 8:50 PM, Christopher Wright <dhasenan@gmail.com> wrote:
>> Jarrett Billingsley wrote:
>>>
>>> I just don't think it's possible.  If all classes had default ctors, it'd be easy; is(typeof(new T)) would be false if and only if T were abstract.  But since that's not the case, I can't think of a way to generically see if a given class type is abstract.  Any ideas?
>>>
>>> It's always a little frustrating when doing type introspection and having to rely on weird side-effects and properties of types, when the compiler is just keeping it in some flag or field somewhere.  Sigh. "is(T == abstract)"?  :P
>>
>> If you know the constructor arguments in advance, you can do something like:
>> static if (is (typeof (new Foo (1, "hello")))){}
>
>Oh, definitely.  But I'm writing a library where the ctor signatures are provided by the user, and "new T(InitsOf!(Types))" could fail either because T is abstract or because they just gave an invalid signature
>
>> Unfortunately, ParameterTupleOf!(T._ctor) doesn't work:
>>
>> class AFoo {}
>> if (is (typeof (AFoo._ctor))) Stdout.formatln ("AFoo._ctor");
>> if (is (typeof (ParameterTupleOf!(AFoo._ctor)))) Stdout.formatln
>> ("AFoo._ctor params");
>> // prints AFoo._ctor
>>
>> _ctor is a really odd construct -- spotty support, not advertised.
>
>I wish it worked right.  Constructors are always the odd ones out. They're just functions, and should be introspectable as such.

Even D2 doesn't provide a way of getting constructor info except for the useless "__ctor" returned by __traits(allMembers). It is also possible to make a useless call to the default constructor in a funky manner:

class C
{
    this()
    {
        writefln("Ctor");
    }

   this(int x)
   {
   }

    void foo()
    {
        __traits(getMember, C, "__ctor");
    }
}


void main()
{
    auto c = new C;
    c.foo(); // re-constructing the object
}

In other words, there is no introspection for constructors at all.