2015-12-21 49 views
1

如果我限定在模块级结构,我可以参考尚未定义的结构。结构声明为了

struct S { 
    ComesLater c; 
} 
struct ComesLater {} 

但是如果我做同样的unittest或功能块里面,这是行不通的:

unittest { 
    struct S { 
    ComesLater c; 
    } 
    struct ComesLater {} 
} 

Error: undefined identifier 'ComesLater'

这是为什么?我如何在函数内部获得与订单无关的声明? d中是否有某种前瞻性声明?我需要这个,因为我使用mixin生成结构,并且按照它们内部依赖性的顺序对声明进行排序,如果存在循环引用结构,那么这将非常费力,有时甚至是不可能的。 (使用指针)内

回答

2

声明功能,单元测试,或其他任何地方的语句实际上可以被执行,则确实是为了依赖,因为它们的价值可能取决于他们的代码运行前。想一个局部变量:

int a; 
writeln(a); 
a = b; 
int b = get_user_line(); 

如果命令不重要,那么两个函数何时会被调用?在重写声明之前,会在写入之前向用户请求一行?

使B中的未定义的变量误差的当前行为保持它简单明了。

它的工作原理无关的顺序在其他情况下,因为没有可执行的代码,它可以依靠,所以没有问题,如果编译器需要在内部想想不同的是可以改变的。

所以:

我怎样才能进去功能顺序无关的声明?

更改上下文,以便没有可执行代码......将它全部放入另一个结构中!

void main() { // or unittest { } 
     struct Holder { 
       static struct S { 
         C c; 
       } 
       static struct C {} 
     } 
} 

由于执行发生在持有者周围,并且不在其内部发生,所以内部声明的顺序再次无关紧要。由于您可以在结构中定义几乎任何东西,因此可以将其用于变量,函数和其他结构等。基本上你所要做的就是将你现有的代码包装在struct Holder {}括号内。

通过将所有内容都设置为静态,您可以像使用容器一样使用它,并在外部引用Holder.S等。

+0

不错!恐怕我无法使用这种解决方法,因为我可能会在同一个作用域内生成多个这样的结构块,并且这只能运行一次。 (那么持有人将会被定义。)你有没有可能得到某种前瞻性声明?或者定义一个没有执行顺序的代码块,但不会改变当前的作用域? (类似于持有者) – Tamas

+2

我能够将结构放在一个'mixin模板Foo(){static struct S {C c; }} static struct C {}}'然后调用'mixin Foo!();'然后我得到独立的顺序块,没有额外的持有者! =) – Tamas

+0

那么,每次创建名称时都可以更改名称。 Holder,Lynch,Mukasey,Gonzales :)或者Holder1,Holder2。 __LINE__技巧可以帮助您在字符串mixin生成代码中创建独特的名称。您也可以尝试使持有者成为'mixin template'而不是'struct',然后在声明后立即将其混合,以便将其符号引入父范围。 –