Templates 使用mixin时有关重写方法的警告

Templates 使用mixin时有关重写方法的警告,templates,d,overriding,Templates,D,Overriding,我想使用mixin实现一个接口。在我创建子类之前,这一切都很好。问题是mixin模板还实现了一个模板函数 比如: interface Features { void feature1(); void feature2(); } mixin template FeaturesImplementer() { int bar; final void feature1(){} void feature2(){} void typeStuff(T)(){}

我想使用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无法使用Feature.FeaturesImplementer覆盖最终函数!()特点1

弃用:使用Feature.FeaturesImplementer隐式重写基类方法!().Feature 2还带有一个WithFeature.FeaturesImplementer!()功能2已弃用;添加“覆盖”属性

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


我可以将
typeStuff
放在另一个模板中,但问题是在
FeaturesImplementer
中,所有内容都一起进行。即使是整数也会被功能使用。有没有一种方法可以始终将同一个mixin与everuthing inside一起使用?

您可以使用在编译时求值的表达式,通过一些静态检查来实现这一点。我们的想法是验证实现是否已经在这里,特别是使用traits

如果是第一次混合模板,您还必须使用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字段,原始代码中还有一个隐藏的问题,根据您铸造实例的方式,该字段可能是
with feature
AlsoWithFeature
中的一个,但是我不知道为什么编译器没有对此抱怨。

为什么还要将它混合到子类中?它将从基类继承而来,而不继承它…因为否则typestuff()将无法工作。它包含处理此的代码,如果不重新混合,这总是与模板混合的类型相同。啊,语言对此有一个答案:好吧,你的问题是最终的方法。把最后一个方法放在一个混合中是没有意义的,就像你在你的例子中那样。是的,这是问题的答案,但我认为解决问题的办法是只在一个方法中使用一个模板这个参数,然后不要再将它混合到子类中。实际上我已经知道一些静态的东西了@问题是指针不在-this-变量上,指针在trait getMember的结果上,但是trait getMember已经使用了好的类型(T)?@AdamD.Ruppe:如果您感兴趣,您可以检查,如果您认为真正的问题得到了更好的解释。