SFINAE error with enumeration template parameter

Can someone explain the following behavior (I am using Visual Studio 2010).
header:

#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;}

source:

bool b = goToWork<MONDAY>();

the compiler gives

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

and

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

But if I change the function template parameter from the WeekDay enum type to int, it compiles fine:

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;}

Also, the standard template function specializes perfectly, there are no surprises:

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

To make things even weirder if I modify the source file to use any other WeekDay than MONDAY or TUESDAY, i.e. bool b = goToWork<THURSDAY>();The error changes to this:

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)  

EDIT: Perhaps someone can test this with a different compiler (other than Visual Studio 2010) to see if the same thing happens because it makes no sense.

EDIT: "" . , == != , :

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;}

EDIT: , , Microsoft: " , . , , Visual Studio. - int."

( , " " Visual Studio 2010)

+3
1

GCC 4.2.1.

, VC , sloppily enum int, int (, 0 1).

+2

Source: https://habr.com/ru/post/1743945/


All Articles