1

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

simples 方法不起作用,因为由于某种原因静态变量在编译时不起作用:

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

struct S1 {
  enum ordinal = nextOrdinal();
}

struct S2 {
  enum ordinal = nextOrdinal();
}

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

-- 灵感来自 Boost.units 维度分析。

4

2 回答 2

2

编译时没有变量(CTFE 函数内部的特殊情况除外)——一切都必须是常量。此外,允许 CTFE 变量变为静态并污染解释环境将是一个非常不确定的设计选择。

部分问题是编译器(据我所知)对各种代码单元的编译顺序没有做出任何保证,甚至(将来)可能能够并行编译片段。通常,您需要将编译时编程视为非常严格的功能环境,具有小范围的灵活可变性(在 CTFE 函数内部)。为确保一致性,支持 CTFE 的函数必须是纯函数,并且“执行的表达式不得引用任何全局或局部静态变量”。http://dlang.org/function.html#interpretation

简而言之,我认为没有任何方法可以让编译器为您存储此状态。

于 2012-08-03T16:34:45.200 回答
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;
}
于 2012-08-03T17:19:15.003 回答