2015-12-21 48 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',然後在聲明後立即將其混合,以便將其符號引入父範圍。 –