关于使用mixin时覆盖方法的警告

时间:2015-11-17 18:37:41

标签: templates d override

我想使用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;
}

输出:

  

错误:函数AlsoWithFeature.FeaturesImplementer!()。feature1无法覆盖最终函数WithFeature.FeaturesImplementer!()。feature1

     

弃用:隐式覆盖基类方法WithFeature.FeaturesImplementer!()。feature2 with AlsoWithFeature.FeaturesImplementer!()。feature2 deprecated;添加'覆盖'属性

     

错误:mixin AlsoWithFeature.FeaturesImplementer!()错误实例化

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

1 个答案:

答案 0 :(得分:1)

您可以使用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字段被重新声明,原始代码中也存在隐藏问题,具体取决于您投放实例的方式,该字段可能是WithFeatureAlsoWithFeature的字段,但我不知道为什么编译器没有抱怨这个。