2010-05-04 165 views
3

有人可以解釋以下行爲(我正在使用Visual Studio 2010)。
標題:SFINAE與枚舉模板參數失敗

#pragma once 
#include <boost\utility\enable_if.hpp> 
using boost::enable_if_c; 

enum WeekDay {MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY}; 

template<WeekDay DAY> 
typename enable_if_c< DAY==SUNDAY, bool >::type goToWork() {return false;} 

template<WeekDay DAY> 
typename enable_if_c< DAY!=SUNDAY, bool >::type goToWork() {return true;} 

來源:

bool b = goToWork<MONDAY>(); 

編譯這給

error C2770: invalid explicit template argument(s) for 'enable_if_c<DAY!=6,bool>::type goToWork(void)' 

error C2770: invalid explicit template argument(s) for 'enable_if_c<DAY==6,bool>::type goToWork(void)' 

但是,如果我改變函數模板p從枚舉類型平日arameter爲int,它編譯罰款:

template<int DAY> 
typename enable_if_c< DAY==SUNDAY, bool >::type goToWork() {return false;} 

template<int DAY> 
typename enable_if_c< DAY!=SUNDAY, bool >::type goToWork() {return true;} 

而且正常功能模板專業化工作正常,沒有驚喜出現:

template<WeekDay DAY> bool goToWork()   {return true;} 
template<>    bool goToWork<SUNDAY>() {return false;} 

爲了使事情更離奇,如果我改變源文件使用任何其他工作日比周一或週二,即bool b = goToWork<THURSDAY>();錯誤更改爲:

error C2440: 'specialization' : cannot convert from 'int' to 'const WeekDay' 
Conversion to enumeration type requires an explicit cast (static_cast, C-style cast or function-style cast) 

編輯:也許有人會用DIF測試此(Visual Studio 2010除外),看看是否發生同樣的事情,因爲它似乎沒有任何意義

編輯:我發現了一個新的「有趣」的這一行爲方面。也就是說,如果我改變與==!=運營模板參數的直接比較與一個輔助結構模板的比較,它工作正常:

template<WeekDay DAY> 
struct Is 
{ 
    static const bool Sunday = false; 
}; 

template<> 
struct Is<SUNDAY> 
{ 
    static const bool Sunday = true; 
}; 

template<WeekDay DAY> 
typename enable_if_c< Is<DAY>::Sunday, bool >::type goToWork() {return false;} 

template<WeekDay DAY> 
typename enable_if_c< !Is<DAY>::Sunday, bool >::type goToWork() {return true;} 

編輯: 順便說一句,我犯了一個錯誤報告,這是微軟的答案:「這是一個在嘗試提升非類型模板參數時出現的錯誤,不幸的是,由於我們對此版本的資源限制以及可用的解決方法,我們無法修復這在Visual Studio的下一個版本中。解決方法是將模板參數類型更改爲int。「

(我覺得 「這個版本」 是指到Visual Studio 2010)在GCC 4.2.1

回答

2

工作正常。

看起來像是VC的模板引擎缺少枚舉類型的比較運算符,或者它傾向於將enum轉換爲int,然後決定嚴格並且不允許向int進行隱式轉換(顯然0和1的例外)。

+0

很高興知道我還沒瘋過。我還懷疑操作符在某種程度上是不存在的,因爲不僅比較運算符==和!=而且也是邏輯運算符&&和||肆虐。對不起,忽略mac用戶。 – zeroes00 2010-05-06 19:48:24