Получение логического значения из true_type / false_type typedef из зависимого класса в enable_if

#c #templates #metaprogramming

#c #шаблоны #метапрограммирование

Вопрос:

У меня есть класс

 template <typename T>
struct Trait { typedef std::false_type IsGood; };

template <>
struct Trait<int> { typedef std::true_type IsGood; };
  

Подобный вызов не удается скомпилировать в MSVC 2010

 template <typename T, typename Enable = void> class Foo;

template <typename T>
class Foo <T, std::enable_if<typename Trait<T>::IsGood::value>::type>
{};

// This fails as well
template <typename T>
class Foo <T, typename std::enable_if<Trait<T>::IsGood::value>::type>
{};

// And this fails horribly
template <typename T>
class Foo <T, typename std::enable_if<typename Trait<T>::IsGood::value>::type>
{};
  

в то время как

 template <typename T>
class Foo <T, typename std::enable_if<std::is_same<std::true_type, 
    typename Trait<T>::IsGood>::value>::type>
{};
  

работает — почему?

Сообщение об ошибке:

 main.cpp(12): error C2039: 'type' : is not a member of 'std::tr1::enable_if<_Test>'
          with
          [
              _Test=false
          ]
main.cpp(12): error C2146: syntax error : missing ',' before identifier 'type'
main.cpp(12): error C2065: 'type' : undeclared identifier
main.cpp(13): error C2976: 'Foo' : too few template arguments
  

Ответ №1:

Вы используете typename не в том месте. Это правильно:

 template <typename T>
class Foo <T, typename std::enable_if<Trait<T>::IsGood::value>::type>
{};        // ^^^^^^^ here should be typename
  

Теперь он компилируется нормально: http://ideone.com/0SwO9

Но вы используете typename как:

 template <typename T>
class Foo <T, std::enable_if<typename  Trait<T>::IsGood::value>::type>
{};                        //^^^^^^^ wrong place
  

Trait<T>::IsGood::value это не тип, поэтому вы не можете применить typename к нему.

Сообщение об ошибке GCC очень четкое:

prog.cpp:12:62: ошибка: несоответствие типа / значения в аргументе 1 в списке параметров шаблона для ‘template<bool <anonymous>, class _Tp> struct std::enable_if’

Посмотрите сами : http://ideone.com/9ujJv

Комментарии:

1. Не компилируется с использованием MSVC2010. Ошибка компилятора?

2. И вот мы идем: connect.microsoft.com/VisualStudio/feedback/details/693591 /…

3. @Anteru: Вам лучше также упомянуть ссылку на эту тему в microsoft connect.