Вопрос

Может кто-то объяснить следующее поведение (я использую 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)'

Но если я изменим параметр шаблона функции в будний день типа Enum для 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;}

Чтобы сделать вещи даже Weirder, если я изменим исходный файл, чтобы использовать любой другой выходний, чем в понедельник или вторник, то есть 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), чтобы увидеть, будет ли одно и то же самое, потому что это не имеет никакого смысла

Редактировать: Я нашел новый «интересный» аспект такого поведения. То есть если я изменив прямое сравнение параметра шаблона с == а также != Операторы в сравнении с шаблоном структуры помощника, он работает нормально:

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: «Это ошибка, которая проявляется при попытке продвижения параметра шаблона не типа. К сожалению, учитывая наши ограничения ресурсов для этого выпуска и что работа -Around доступно, мы не сможем это исправить в следующем выпуске Visual Studio. Работа - вокруг - это изменить тип параметра шаблона в INT ».

(Я думаю, что «этот релиз» относится к Visual Studio 2010)

Это было полезно?

Решение

Работает нормально в GCC 4.2.1.

Похоже, либо шаблон шаблона VC, отсутствует операторы сравнения для типов Enum, или он небрежно преобразовал Enum int, а затем решил быть строгим и запретить неявное преобразование в int (по-видимому, с исключением для 0 и 1).

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top