誰かが次の動作を説明できますか (私は Visual Studio 2010 を使用しています)。
ヘッダ:
#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)'
しかし、関数テンプレート パラメーターを列挙型 WeekDay から 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;}
さらに奇妙なことに、ソース ファイルを MONDAY または TUESDAY 以外の WeekDay を使用するように変更する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)
編集:おそらく誰かが別のコンパイラ(Visual Studio 2010以外)でこれをテストして、同じことが起こるかどうかを確認できます.
編集: この動作の新しい「興味深い」側面を見つけました。つまり、テンプレート パラメーターと==
and!=
演算子の直接比較をヘルパー構造体テンプレートとの比較に変更すると、正常に動作します。
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;}
編集: ところで、私はバグ レポートを作成しましたが、これは Microsoft からの回答です: -回避策が利用可能です。Visual Studio の次のリリースではこれを修正できません。回避策は、テンプレート パラメーターの型を int に変更することです。"
(「このリリース」は Visual Studio 2010 を指していると思います)