2012-04-04 50 views
5

做給定一個模板專營模板

template <int n> 
void f(){...}; 

我知道我可以專注它的n具體數值

template <> 
void f<2>(){...}; 

但是,有沒有這讓我的方法專門爲所有積極n

我以爲做以下

template <int n> 
void f<n>(){ 
    int dummy[n]; //invalid for n < 0 
    ... 
}; 

的所以對於n<0這個代碼無效,編譯器會訴諸於以前的定義。不幸的是,我得到的只是一個redefinition of 'void f<n>()'錯誤。

注:我猜這可能不是標準支持。我問是否沒有某種方法(可能是一些模板元編程)來實現這種效果。

回答

13

一個選擇是使用另一個間接級別。定義一個輔助模板,其中包含兩個參數 - 數字n和代表n是否爲負數的bool,然後在n爲負數時專用該模板。然後,讓你的f函數實例化具有正確參數的模板。

例如:

template <int n, bool isNegative> struct fImpl { 
    static void f() { 
     /* ... code for when n is positive ... */ 
    } 
}; 
template <int n> struct fImpl<n, true> { 
    static void f() { 
     /* ... code for when n is negative ... */ 
    } 
}; 

template <int n> void f() { 
    fImpl<n, (n < 0)>::f(); 
} 

另一種選擇是使用SFINAE overloading和從C++ 11(或增壓的同等)的std::enable_if模板類;

template <int n> void f(typename std::enable_if<(n < 0)>::type* = 0) { 
    /* ... n is negative ... */ 
} 

template <int n> void f(typename std::enable_if<(n >= 0)>::type* = 0) { 
    /* ... n is positive ... */ 
} 

這些函數將只適用於重載如果n具有正確的符號,所以正確的版本總是會被調用。

希望這會有所幫助!

+5

風格的問題,但我更喜歡把'enable_if'放在返回類型上,所以在混淆的東西(用戶和函數的類型)周圍沒有一個神奇的參數。 – GManNickG 2012-04-04 19:33:24