2012-09-20 37 views
0

我寫這一段代碼來獲得由指針傳遞的各類功能的保持:foreach在編譯時執行嗎?

import std.stdio; 
import std.traits; 

void main() 
{ 
    get_param_types(&f1,"f1"); 
    get_param_types(&f2,"f2"); 
    get_param_types(&f3,"f3"); 
} 

void get_param_types(f_t)(f_t f, string f_id){ 
    writeln("get_param_types "); 
    alias ParameterTypeTuple!(f) ptt; 
    writeln(f_id, " has ", ptt.length, " parameters"); 
    static if (ptt.length){ 
    write("("); 
    foreach (pt; ptt){ 
     write(typeid(pt), " "); 
    } 
    writeln(")"); 
    } 
} 

void f1() { } 
void f2(int x) { } 
void f3(int x, double y, string z) { } 

我的疑問是:1:get_param_types完全在編譯時評價?

如果不是:2:我該如何做到這一點?

雖然我在這... 3:是否有辦法避免將字符串(例如"f1"),並在編譯時從get_param_types內演繹呢?

回答

1
  1. get_param_types()在你的例子在運行時計算,因爲你是在運行時main()調用它。請注意,它不能在編譯時按原樣進行評估,因爲您正在調用write()和writeln()函數,它們會寫入stdout,編譯時不可用。
  2. 你想在編譯時達到什麼目的?所有對writewriteln的調用只能在您的示例的運行時發生。 foreach和和在編譯時進行評估...基本上,對該函數的任何調用都將在運行時調用writewriteln的組合(無循環或條件) - 這是您想要的嗎?
  3. 您可能想要查看template alias parameters。他們看起來有點像這樣:
void getParamTypes(alias fn)() if (isCallable!fn) 
{ 
    writefln("Getting parameter types for fn: %s", (&fn).stringof[2..$]); 
    foreach (param; ParameterTypeTuple!fn) { 
     writeln(param.stringof); 
    } 
} 
+0

「寫入」調用僅用於調試。所以,如果我擺脫它們(或者'調試'它們,我將編輯這個帖子)它將在編譯時執行,對吧?我確信'靜'如果不是'foreach'。 'alias''stringof' combi的作品像魅力! isCallable是什麼?據我可以看到,它只是縮短了錯誤消息,當我調用一個不可調用的函數... – steffen

+0

foreach()將在迭代元組時迭代在編譯時展開。也就是說,在運行時不會有迭代,它只是一個語句列表。 isCallable指定別名必須是可以調用的東西(具有opCall()的函數,委託,結構或類)。它往往會使用法和錯誤信息更清晰。 – Robert

3

在foreach將在編譯時間,但執行代碼擴展(如運行時只喜歡寫功能)可以被推遲到運行時

這是相當於循環展開,但這裏不是用計數器,而是每次迭代的唯一類型