Thread overview
Getting the parameters of a struct/class constructor
Jan 24, 2013
Rob T
Jan 24, 2013
mist
Jan 24, 2013
Rob T
Jan 24, 2013
Philippe Sigaud
Jan 24, 2013
Andrej Mitrovic
Jan 25, 2013
Rob T
January 24, 2013
Hello all,

Is there a way to construct a tuple of the types that need to be passed to a struct or class's constructor?

I tried using ParameterTypeTuple either on the class or its constructor:

     ParameterTypeTuple!A

or

     ParameterTypeTuple!(A.this)

... but neither works: the former generates an error,

     Error: template instance ParameterTypeTuple!(A) ParameterTypeTuple!(A) does
not match template declaration ParameterTypeTuple(func...) if (func.length == 1
&& isCallable!(func))

while the latter generates,

     Error: identifier expected following '.', not 'this'

A (broken) bit of sample code is attached which illustrates what I'm trying to achieve.  Can anyone advise?

Thanks & best wishes,

      -- Joe


January 24, 2013
There may be more than one "this", so you'll have to specify the args for each specific constructor manually.

Disclaimer: Someone else may have a better solution as I'm not that much of an expert in this area.

This sample may point you in the right direction ...

import std.typetuple;

struct X
{
    alias TypeTuple!(int, double) CONSTUCT1;
    alias TypeTuple!(int, double, string) CONSTUCT2;

    this( CONSTUCT1 args )
    {
        alias args[0] a_int;
        alias args[0] a_double;

        _a = a_int;
        _b = b_double;

    }

    this( CONSTUCT2[0] a_int, CONSTUCT2[1] b_double, CONSTUCT2[2] c_string  )
    {

        _a = a_int;
        _b = b_double;
        writeln(c_string);
    }

    int _a;
    double _b;

}


void foo(X.CONSTUCT1[0] a, X.CONSTUCT1[1] b )
{

  ...

}

void bar(X.CONSTUCT2 args )
{

   alias args[0] a_int;
   alias args[1] a_double;
   alias args[2] a_string;
  ...

}

Hope this helps.

--rt
January 24, 2013
You can use "magic" functions __ctor and __dtor which actually serve as constructor and destructor implementations behind the scene.

Example and proof-of-concept: http://dpaste.1azy.net/fd924332

Have no idea if it is explicitly defined by spec somewhere though.
January 24, 2013
On Thursday, 24 January 2013 at 18:41:31 UTC, mist wrote:
> You can use "magic" functions __ctor and __dtor which actually serve as constructor and destructor implementations behind the scene.
>
> Example and proof-of-concept: http://dpaste.1azy.net/fd924332
>
> Have no idea if it is explicitly defined by spec somewhere though.

If you have more than one ctor it seems to take the first one

http://dpaste.1azy.net/b994fdf3

I don't know if you will able to rely on the order unless it's a part of the spec.

--rt
January 24, 2013
On Thu, Jan 24, 2013 at 10:34 PM, Rob T <alanb@ucora.com> wrote:
> On Thursday, 24 January 2013 at 18:41:31 UTC, mist wrote:
>>
>> You can use "magic" functions __ctor and __dtor which actually serve as constructor and destructor implementations behind the scene.
>>
>> Example and proof-of-concept: http://dpaste.1azy.net/fd924332
>>
>> Have no idea if it is explicitly defined by spec somewhere though.
>
>
> If you have more than one ctor it seems to take the first one
>
> http://dpaste.1azy.net/b994fdf3
>
> I don't know if you will able to rely on the order unless it's a part of the spec.

IIRC, you can use __traits(getOverloads, mytype.__ctor) to get all
constructor overloads.
See:
http://dlang.org/traits.html#getOverloads

I used this in conjunction with __traits(getMember, ...) to get the entire list of member, overloads included.
January 24, 2013
On 1/24/13, Philippe Sigaud <philippe.sigaud@gmail.com> wrote:
> IIRC, you can use __traits(getOverloads, mytype.__ctor) to get all
> constructor overloads.
> See:
> http://dlang.org/traits.html#getOverloads
>
> I used this in conjunction with __traits(getMember, ...) to get the entire list of member, overloads included.
>

I don't understand why, but it seems DForum doesn't show up any of my posts. I've posted this as my second reply (hope this makes it):

If you have multiple constructors you can pick the parameters with a helper template:

import std.traits, std.string;

struct A
{
        this(int a, double b)
        {
        }

    this(float y)
    {
    }
}

template PickCtorParams(Type, size_t index)
{
    enum ctorLen = __traits(getOverloads, Type, "__ctor").length;
    static if (index < ctorLen)
    {
        alias ParameterTypeTuple!(__traits(getOverloads, A,
"__ctor")[index]) PickCtorParams;
    }
    else
    {
        static assert(0,
            format("index %s exceeds %s ctors for type %s", index,
ctorLen, Type.stringof));
    }
}

void main()
{
    pragma(msg, PickCtorParams!(A, 0));  // (int, double)
    pragma(msg, PickCtorParams!(A, 1));  // (float)
    pragma(msg, PickCtorParams!(A, 2));  // out of bounds
}
January 25, 2013
On Thursday, 24 January 2013 at 22:49:33 UTC, Andrej Mitrovic wrote:
> On 1/24/13, Philippe Sigaud <philippe.sigaud@gmail.com> wrote:
>> IIRC, you can use __traits(getOverloads, mytype.__ctor) to get all
>> constructor overloads.
>> See:
>> http://dlang.org/traits.html#getOverloads
>>
>> I used this in conjunction with __traits(getMember, ...) to get the
>> entire list of member, overloads included.
>>
>
> I don't understand why, but it seems DForum doesn't show up any of my
> posts. I've posted this as my second reply (hope this makes it):
>

The thread got split up into two separate threads. Your missing post shows up in the split. I really hate it when it does this.

--rt