确保每个结构都有唯一的序号

时间:2012-08-03 16:17:06

标签: d

我希望能够创建结构,每个结构都有一个指示结构(而不​​是对象)顺序的成员。应该没有运行时开销,我应该能够在编译时使用序号。

简单方法不起作用,因为某些原因静态变量在编译时不起作用:

int nextOrdinal() {
  static int ordinal;
  return ordinal++;
}

struct S1 {
  enum ordinal = nextOrdinal();
}

struct S2 {
  enum ordinal = nextOrdinal();
}

此时如何创建结构对我来说并不重要。问题似乎是在编译时不可能保留状态,我是否正确?

--Inspired by Boost.units dimensional analysis.

2 个答案:

答案 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;
}