2014-01-24 103 views
0

如果函數的參數會在編譯時知道,是否正確將它變成模板參數?將「正常」參數變爲模板化參數是否正確?

採取下面的代碼作爲示例:

template<typename ... P> void 
    LOG 
    (const severity_level & l , const P & ... p) 
    { 
     // Take the parameters from 'p' and use it to construct a message. 
     // Then, prepend a string depending on the severity level specified. 
    } 

作爲嚴重性水平始終一個編譯時間常數,我可以這樣做:

template<severity_level L , typename ... P> void 
    LOG 
    (const P & ... p) 
    { 
     // Call me like this: LOG<debug>("this is a debugging message") 
    } 

隨着稍加修改到源代碼,我可以擺脫一個參數。這個解決方案有什麼缺點,還是很好?

最好的問候, Kalrish

P.S:這另一個好處是更容易編譯時過濾,在這個例子中,日誌記錄調用。

+2

你自己提到了缺點:1)必須在編譯時知道,2)不再有「記錄一個函數」。請注意,* call網站*當然會在編譯時知道嚴重級別,但模板化版本禁止在日誌管道中的任何位置編寫通用代碼*。 – Jon

+0

@DanielFrey你說得對,對不起。糾正。 – Kalrish

+0

@ a.lasram這是一個枚舉示例。關於參考,我不明白你的意思。 FWIW,我剛剛修復了一個錯誤(將'typename L'改爲'severity_level L')。 – Kalrish

回答

1

除了被限制爲編譯時值以外,非類型模板參數僅限於某些類型:積分,枚舉,指針,左值引用,指向成員或指向類型的指針。所以如果一個參數不是其中之一,那麼你就不能將它轉換爲模板參數。當然,嚴重程度可能是一個枚舉,所以這可能很好。

需要記住的一件事是,即使您的代碼現在與需求相匹配,未來您可能也想進行更改,如果以這種方式限制自己,則可能會更困難。例如,也許您最終會根據用戶選項根據不同的嚴重級別進行一些消息日誌記錄。

除非您能確定具體的好處,否則您應該避免進行更改。

1

我可以想象有人想寫如下代碼。

severity_level level = none; 
if (discrepancy > .05) 
{ 
    level = fatal; 
} 
else if (discrepancy > .01) 
{ 
    level = warning; 
} 

if (level != none) 
{ 
    //Taking some liberty with the printf-like signature... 
    LOG(level, "Discrepancy in thingamabob: %f", discrepancy); 
} 

因此使用模板化方法是一個壞主意。

+0

可以通過使用函數指針輕鬆解決;) – PlasmaHH

+1

@PlasmaHH「很容易」哈哈 –

+0

我從來沒有真正看到這種使用類型的需要。您可以將日誌移至if語句中,然後針對不同的嚴重級別提供不同的信息。 – DaBrain