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);
}
}