Is there a cleaner way of doing this?

Ali Çehreli via Digitalmars-d digitalmars-d at puremagic.com
Mon Aug 7 02:33:46 PDT 2017


On 08/07/2017 01:01 AM, Shachar Shemesh wrote:
> It is often desired to have a struct with an extra parameter. The common
> way to do this is like so:
>
> struct S(T) {
>     T param;
>
>     void initialize(T param) {
>         this.param = param;
>         // Other stuff
>     }
> }
>
> The problem is what happens when the param is optional. The common way
> to do this is to set T to void. This results in the following code:
>
> struct S(T) {
>     enum HasParam = !is(T == void);
>     static if( HasParam ) {
>         T param;
>     }
>
>     static if( HasParam ) {
>         void initialize(T param) {
>             this.param = param;
>             // Other stuff
>         }
>     } else {
>         void initialize() {
>             // Same other stuff as above!
>         }
>     }
> }
>
> This is both tedious and error prone. Is there a cleaner way of doing this?

A mixin template can work. The whole param-related code is in one place 
and the void specialization obviates the need for static if:

mixin template ParamCode(T) {
     T param;

     void initializeParam(T param) {
         this.param = param;
         initialize();
     }
}

template ParamCode(T : void) {
}

struct S(T) {
     mixin ParamCode!T;

     void initialize() {
         // ...
     }
}

unittest {
     auto a = S!int();
     static assert(a.sizeof == int.sizeof);
     a.initializeParam(42);

     auto b = S!void();
     static assert(b.sizeof == 1);
     b.initialize();
}

void main() {
}

Ali



More information about the Digitalmars-d mailing list