我希望能够创建结构,每个结构都有一个指示结构(而不是对象)顺序的成员。应该没有运行时开销,我应该能够在编译时使用序号。
简单方法不起作用,因为某些原因静态变量在编译时不起作用:
int nextOrdinal() {
static int ordinal;
return ordinal++;
}
struct S1 {
enum ordinal = nextOrdinal();
}
struct S2 {
enum ordinal = nextOrdinal();
}
此时如何创建结构对我来说并不重要。问题似乎是在编译时不可能保留状态,我是否正确?
答案 0 :(得分:2)
编译时没有变量(除了CTFE函数内部的特殊情况) - 一切都必须是常量。此外,允许CTFE变量变为静态并污染解释的环境将是一个非常不确定的设计选择。
问题的一部分是编译器没有(据我所知)保证各种代码单元的编译顺序,甚至可能(将来)能够并行编译片段。通常,您需要将编译时编程视为一个非常严格的功能环境,具有一小部分灵活的可变性(在CTFE函数内部)。为了确保一致性,CTFE功能必须是纯粹的,并且“执行的表达式可能不会引用任何全局或局部静态变量”。 http://dlang.org/function.html#interpretation
简而言之,我认为没有办法让编译器为你存储这种状态。
答案 1 :(得分:0)
我不知道这样做的可行方法,但是如果你想根据它们在源文件中的位置来订购它们,你可以这样做:
import std.conv;
import std.stdio;
size_t nextOrdinal(size_t line = __LINE__)()
{
return line;
}
struct S1 {
enum ordinal = nextOrdinal();
}
struct S2 {
enum ordinal = nextOrdinal();
}
void main()
{
writeln(S1.ordinal);
writeln(S2.ordinal);
}
如果您有多个调用nextOrdinal
的文件,您最终可能会得到具有相同序数值的结构定义。您也可以考虑对文件名进行编码:
size_t nextOrdinal(string file = __FILE__, size_t line = __LINE__)()
{
size_t res;
foreach (ch; file)
res += ch;
return res + line;
}