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

D 确保每个结构都有唯一的序号,d,D,我希望能够创建结构,每个结构都有一个表示结构(而不是对象)顺序的成员。应该没有运行时开销,我应该能够在编译时使用序号 simples方法不起作用,因为出于某种原因,静态变量在编译时不起作用: int nextOrdinal() { static int ordinal; return ordinal++; } struct S1 { enum ordinal = nextOrdinal(); } struct S2 { enum ordinal = nextOrdinal()

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

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

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

struct S1 {
  enum ordinal = nextOrdinal();
}

struct S2 {
  enum ordinal = nextOrdinal();
}
目前,结构是如何创建的对我来说并不重要。问题似乎是不可能在编译时保留状态,对吗


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

问题的一部分在于,据我所知,编译器没有对各种代码单元的编译顺序做出任何保证,甚至可能(将来)能够并行编译各个代码单元。一般来说,您需要将编译时编程视为一个非常严格的函数环境,具有少量灵活的可变性(在CTFE函数中)。为确保一致性,CTFE-able功能必须是纯粹的,并且“经过切割的表达式不得引用任何全局或局部静态变量。”


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

我不知道有可靠的方法可以做到这一点,但是如果您想根据它们在源文件中的位置对它们进行排序,您可以这样做:

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

这是行不通的,因为您可以在同一行上定义多个结构。然而,我确实有一个解决方案,我可能会在以后发布;它要求用户提供序号,如果以前使用过该序号,则会产生编译时错误。我假设您希望所有内容都是自动的。我不知道是谁在同一行上写了多个结构定义(tbh.:)没错,我认为没有办法让编译器存储状态,但有办法在编译时为结构分配唯一的序号。我很快会发布我的解决方案。如果程序员提供,当然可以。让编译器检查唯一性应该是很有可能的,因为它无论如何都可以做到这一点(例如,同一模块中的两个具有相同名称的结构)。对,但不能使用结构,因为可以使用具有相同名称的局部和全局结构,并且它们不会产生编译时错误。