2011-07-14 56 views
4

我有一個帶有模板參數的類,它應該決定它包含的兩種數據類型中的哪一種。基於這個參數,我想用兩種不同的方式實現一個成員函數。我嘗試使用Boost Enable-If,但沒有成功。下面是我最吃驚不工作的代碼版本:基於類模板參數專門化C++成員函數

#include <boost/utility/enable_if.hpp> 
enum PadSide { Left, Right }; 
template <int> struct dummy { dummy(int) {} }; 

template <PadSide Pad> 
struct String 
{ 
    typename boost::enable_if_c<Pad == Left, void>::type 
     getRange(dummy<0> = 0) {} 
    typename boost::enable_if_c<Pad == Right, void>::type 
     getRange(dummy<1> = 0) {} 
}; 

int main() 
{ 
    String<Left> field; 
    field.getRange(); 
} 

對此,G ++ 4.6.0說:

no type named ‘type’ in ‘struct boost::enable_if_c<false, void>’ 

當然,第二個重載應該不工作,但由於SFINAE,它應該被忽略。如果我刪除虛擬函數的參數,G ++這樣說:

‘typename boost::enable_if_c<(Pad == Right), void>::type 
    String<Pad>::getRange()‘ 
cannot be overloaded with 
‘typename boost::enable_if_c<(Pad == Left), void>::type 
    String<Pad>::getRange()‘ 

這就是爲什麼我把假人蔘數出現在首位 - 以下的the documentation編譯器變通方法部分。

基本上我想要的是getRange()的兩個實現,並且根據Pad類型選擇一個或另一個。我希望Enable-If能讓我做到這一點,而不需要輔助類來委託工作(我將在此期間嘗試)。

+1

SFINAE不工作,因爲它只能用於模板。這些函數不是模板函數 - 它們只是模板類的成員。 –

+0

您可以通過添加模板類型T將構造函數作爲模板函數,並將其默認值分配爲「Pad」,但seam VS不支持模板函數的默認參數。 – ZijingWu

回答

7

由於您打算製作getRange()的兩個不同版本,您總是可以使您的struct String成員函數超載,具體取決於PadSide的類型。我知道這不是很「漂亮」,但最終,它仍然是一個類似的代碼量,並且您不必製作多個類類型。

template<PadSide Pad> 
struct String 
{ 
    void getRange(); 
}; 

template<> 
void String<Right>::getRange() { /*....*/ } 

template<> 
void String<Left>::getRange() { /*....*/ } 
+0

+1,正在思考相同的路線。 – iammilind

+0

太棒了。我之前試圖做這樣的事情,但得到的語法/方法有點不對。謝謝。 –