“这个T”的怪异行为

时间:2017-10-19 21:57:57

标签: templates d typetraits

有人可以向我解释以下行为吗?

使用这样的基类:

abstract class Foo
{
    string[] members;

    final:

    this(this T)(T child)
    {
        import std.conv : to;

        foreach (member; __traits(derivedMembers, T))
        {
            mixin("members ~= to!string(child." ~ member ~ ");\r\n");
        }
    }

    void printMembers()
    {
        writeln(members);
    }
}

我希望成员可以使用传递的子类型的值填充。

但是这种行为真的很奇怪。

数组成员将无限填充,这基本上会导致程序内存不足。

如果您将mixin更改为:

mixin("if (members.length < 20) members ~= to!string(child." ~ member ~ ");\r\n");

然后你将能够看到如何填充数组,但是这些值在代码应该如何工作方面没有意义。

使用示例:

class Bar : Foo
{
    int baba;
    int caca;

    this() { baba = 1; caca = 2; super(this); }
}

class Baz : Foo
{
    int foo;
    int bar;
    int baz;

    this() { foo = 100; bar = 200; baz = 300; super(this); }
}

void main()
{
    auto b = new Bar();
    auto a = new Baz();

    b.printMembers();
    a.printMembers();
    b.printMembers();
}

上面的代码将生成如下输出:

["1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "f193.Bar", "f193.Bar", "f193.Bar", "f193.Bar", "f193.Bar", "f193.Bar", "f193.Bar", "f193.Bar", "f193.Bar"]
["100", "200", "300", "100", "200", "300", "100", "200", "300", "100", "200", "300", "100", "200", "300", "100", "200", "300", "100", "200", "f193.Baz", "f193.Baz", "f193.Baz", "f193.Baz", "f193.Baz", "f193.Baz"]
["1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "f193.Bar", "f193.Bar", "f193.Bar", "f193.Bar", "f193.Bar", "f193.Bar", "f193.Bar", "f193.Bar", "f193.Bar"]

我期望的地方如下:

["1", "2"]
["100", "200", "300"]
["1", "2"]

为什么它的行为如此?对我来说这看起来像个错误,但也许有这种行为的原因?

1 个答案:

答案 0 :(得分:1)

查看我看到的代码,因为构造函数被称为递归。

简单修复如下:

static if (member != "__ctor") mixin("members ~= to!string(child." ~ member ~ ");\r\n");