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

Reply via email to