2012-08-03 87 views
1

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

的simples方法是行不通的,因为某种原因,静态变量不发生在编译时工作:

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

struct S1 { 
    enum ordinal = nextOrdinal(); 
} 

struct S2 { 
    enum ordinal = nextOrdinal(); 
} 

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

--Inspired by Boost.units dimensional analysis.

回答

2

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

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

总之,我不认为有什么办法让编译器为你存储这个状态。

+0

真的,我不认为有一种方法可以让编译器店的状态,但分配唯一的序数在编译时结构的一种方式。我会很快发布我的解决方案。 – Arlen 2012-08-03 18:04:23

+0

如果程序员提供它们,当然。并且编译器检查唯一性应该是很有可能的,因为它无论如何都会这样做(例如,具有相同名称的同一模块中的两个结构体)。 – 2012-08-03 18:07:43

+0

没错,但是你不能用结构来做,因为你可以拥有同名的局部和全局结构,并且不会产生编译时错误。 – Arlen 2012-08-03 18:11:12

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

这不起作用,因为您可以在同一行中定义多个结构。不过,我确实有一个解决方案,我可能会稍后发布;它会要求用户提供序号,如果之前使用过序号,则会产生编译时错误。 – Arlen 2012-08-03 18:02:18

+1

我假设你想要一切都是自动的。我不知道谁在同一行tbh上写了多个结构定义。 :) – 2012-08-03 19:30:00

相关问题