有人可以解釋以下行爲(我正在使用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
很高興知道我還沒瘋過。我還懷疑操作符在某種程度上是不存在的,因爲不僅比較運算符==和!=而且也是邏輯運算符&&和||肆虐。對不起,忽略mac用戶。 – zeroes00 2010-05-06 19:48:24