D 瞄准!T()不适用于类成员

D 瞄准!T()不适用于类成员,d,D,我正在尝试使用范围!在程序类中分配的T()模板,用于保存分配。我无法让它工作,但出现以下异常 Error: cannot cast &Scoped([void, void, void, void, void, void, void, void, void, void, void, void, void, void, void, void, void, void, void, void, void, void, void, void, void, void, void, void, voi

我正在尝试使用范围!在
程序
类中分配的T()模板,用于保存分配。我无法让它工作,但出现以下异常

Error: cannot cast &Scoped([void, void, void, void, void, void, void, void, void, void, void, void, void, void, void, void, void, void, void, void, void, void, void, void, void, void, void, void, void, void, void, void, void, void, void, void, void, void, void, void]).Scoped_store to ulong at compile time
我不是舒尔,如果设计上不能为类成员使用scoped,或者scoped模板中的erorr。如果是故意的,顺便说一下,这是一条非常糟糕的错误消息

下面的代码将演示我的问题

import std.typecons;

public class Foo
{
    int i = 0;
}

public class Program
{
    auto myFoo = scoped!Foo();
}

void main(string[] argv)
{
    new Program();
}
此行将尝试实例化
Foo
类,并在编译期间初始化
myFoo
字段。这是因为
范围有限!Foo()
被解释为默认值,在编译过程中始终计算该值,因此编译器尝试解释该表达式(CTFE)。因为
scoped
做了一些低级的工作,所以CTFE在这种情况下不起作用

相反,您应该在类构造期间的运行时初始化字段:

public class Program
{
    typeof(scoped!Foo()) myFoo;

    this()
    {
        myFoo = scoped!Foo();
    }
}
范围明确的
文档实际上涵盖了这种情况。引用它:

作用域成员变量必须具有 键入
typeof(scoped!Class(args))
,并通过调用 范围。请参见下面的示例

以下是参考示例:

class A
{
    int x;
    this()     {x = 0;}
    this(int i){x = i;}
    ~this()    {}
}

// ...

// Use as member variable
struct B
{
    typeof(scoped!A()) a; // note the trailing parentheses

    this(int i)
    {
        // construct member
        a = scoped!A(i);
    }
}

嗯,好的。但是如果用
pure
注释ctor,那么在编译时是否可以构造
A
?这样编译人员就可以知道了。这是没有实现还是根本不可能?我刚刚意识到我的要求。纯构造函数在D的意义上是不可能的,但我仍然认为可以在编译时执行的构造函数的概念是可能的,因此这是可能的。也许我忽略了什么。
pure
不是问题所在,而且
pure
构造函数很可能是D定义的
pure
(即不访问全局可变状态)。类甚至可以在编译时构造和使用。但是,要在编译时构造并传递到运行时,它们必须是
不可变的
(由于在运行时堆甚至不存在时在运行时堆上分配引用类型的问题)。而且,
scoped
执行CTFE期间不允许的低级操作,因此它甚至不能在CTFE期间与局部变量一起使用。
class A
{
    int x;
    this()     {x = 0;}
    this(int i){x = i;}
    ~this()    {}
}

// ...

// Use as member variable
struct B
{
    typeof(scoped!A()) a; // note the trailing parentheses

    this(int i)
    {
        // construct member
        a = scoped!A(i);
    }
}