2009-04-22 54 views
6

模板元編程可用於在編譯時計算事件,而不是在運行時。我聽說一些編程競賽對編譯時間的限制正好消除了模板元編程濫用。模板編譯真的需要多長時間?

是否有任何無辜的看例子使用模板,需要一些真的很長時間(如幾個小時)編譯?

回答

3

我聽說國際奧林匹克競賽(一個這樣的編程競賽)首次引入編譯時間限制後,參賽者使用類似this的技術創建了7維矢量。他的代碼不得不在一夜之間編譯,這太糟糕了。我認爲這發生在90年代末的一段時間。

5

模板機制是圖靈完整的。這意味着至少在理論上,任何可以完成的計算都可以在編譯時以這種方式完成(實際上,您可能會很快遇到對模板深度等的嚴格限制,但這與編譯器相關)。

是否要這樣做是一個單獨的問題。通過使用昂貴的算法,您可以輕鬆地匹配您的「編譯小時」標準。但也有更多實用的代碼,如this one implementing an FFT;給該設置足夠大的數據,這將需要一段時間...

+0

這大約需要25秒鐘,酷睿雙核2,66與N = 1000。這令人印象深刻,但不是很長。而這個代碼絕對不是天真地看。 – sharptooth 2009-04-24 16:29:43

+0

對於FFT,N = 1000並不是很大。我應該清楚,我的意思是說它更「實用」,並不是因爲這是你想要計算FFT的方式,而是因爲它是一種非常有用的算法(並且在整個地方使用)而不是僅僅爲了實現需要很長時間(比如和Ackerman功能評估) – simon 2009-04-24 16:38:03

3

試試這個(我用Visual Studio 2005中)

template <int M, int N> 
struct Ack 
{ 
    enum { value = Ack<M - 1, Ack<M, N - 1>::value >::value }; 
}; 

template <int M> 
struct Ack<M, 0> 
{ 
    enum { value = Ack<M - 1, 0>::value }; 
}; 

template <> 
struct Ack<0, 0> 
{ 
    enum { value = 1 }; 
}; 

template <int N> 
struct Ack<0, N> 
{ 
    enum { value = N + 1 }; 
}; 

void main() 
{ 
    printf("Result: %d\n", Ack<150, 150>::value); 
} 

它也許看起來horribble,我只是試着寫一個相當於此可愛的口齒不清功能

(defun ack(m, n) 
cond ((= m 0) (+ n 1)) 
    ((= n 0) ack(- m 1) n) 
    (t (ack (- m 1) (ack m (-n 1)))) 
) 

我們老師說,這是費爾馬功能,但我不知道......