3

誰かが次の動作を説明できますか (私は 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 を指していると思います)

4

1 に答える 1

2

GCC 4.2.1 で正常に動作します。

VC のテンプレート エンジンに enum 型の比較演算子がないか、enum を int にずさんに変換してから、厳密にして int への暗黙的な変換を許可しないことにしたようです (明らかに 0 と 1 は例外です)。

于 2010-05-06T13:20:02.583 に答える