templates – 使用mixin时有关覆盖方法的警告

我想使用mixin来实现一个接口.这工作正常,直到我继承.问题是mixin模板还实现了模板功能.

就像是:

interface Features {
    void feature1();
    void feature2();
}

mixin template FeaturesImplementer() {
    int bar;
    final void feature1(){}
    void feature2(){}
    void typeStuff(T)(){}
}

class WithFeature: Features {
    mixin FeaturesImplementer;
    this(){typeStuff!(typeof(this));}
}

class AlsoWithFeature: WithFeature {
    mixin FeaturesImplementer;
    this(){typeStuff!(typeof(this));}
}

void main() {
    new WithFeature;
    new AlsoWithFeature;
}

输出:

Error: function AlsoWithFeature.FeaturesImplementer!().feature1 cannot override final function WithFeature.FeaturesImplementer!().feature1

Deprecation: implicitly overriding base class method WithFeature.FeaturesImplementer!().feature2 with AlsoWithFeature.FeaturesImplementer!().feature2 deprecated; add ‘override’ attribute

Error: mixin AlsoWithFeature.FeaturesImplementer!() error instantiating

我可以把typeStuff放在另一个模板中,但问题是在FeaturesImplementer中,一切都在一起.功能甚至使用整数.有没有办法在内部使用相同的mixin和everuthing?

最佳答案 您可以使用
static if表达式进行一些静态检查,该表达式在编译时进行评估.我们的想法是使用特征来验证实现是否已经在这里,特别是
hasMember.

如果第一次混合模板,您还必须使用std.traits进行检查,在您的示例中,它等同于检查祖先(对象)是否已经是要素.

例如:

interface Features {
    void feature1();
    void feature2();
}

mixin template FeaturesImplementer() {

    import std.traits: BaseClassesTuple;
    alias C = typeof(this);
    enum OlderHave = is(BaseClassesTuple!C[0] : Features);
    enum Have = is(C : Features);
    enum Base = Have & (!OlderHave);

    static if (Base || !__traits(hasMember, C, "bar"))
    int bar;

    static if (Base || !__traits(hasMember, C, "feature1"))
    final void feature1(){}

    static if (Base || !__traits(hasMember, C, "feature2"))
    void feature2(){}

    void typeStuff(T)(){}
}

class WithFeature: Features {
    mixin FeaturesImplementer;
    this(){typeStuff!(typeof(this));}
}

class AlsoWithFeature: WithFeature {
    mixin FeaturesImplementer;
    this(){typeStuff!(typeof(this));}
}

void main() {
    new WithFeature;
    new AlsoWithFeature;
}

然后,如果不存在,则仅混合不同的功能实现.

请注意,由于int字段被重新声明,原始代码中也存在隐藏的问题,具体取决于您实例化的方式,字段可能是WithFeature或AlsoWithFeature,但我不知道编译器为什么会这样做不要抱怨.

点赞