Проблема с СФИНАЭ

Почему этот код (значение fnc в классе M) не разрешается правилами SFINAE? Я получаю сообщение об ошибке:

Error   1   error C2039: 'type' : is not a member of
                                   'std::tr1::enable_if<_Test,_Type>'  

Конечно, тип не является членом, он не определен в этой общей версии enable_if, но разве вся идея не заключается в том, чтобы включить эту версию fnc, если логическое значение истинно, и не создавать ее экземпляр, если оно ложно? Может, кто-нибудь объяснит мне это?

#include <iostream>
#include <type_traits>

using namespace std;

template <class Ex> struct Null;
template <class Ex> struct Throw;

template <template <class> class Policy> struct IsThrow;

template <> struct IsThrow<Null> {
    enum {value = 0};
};

template <> struct IsThrow<Throw> {
    enum {value = 1};
};

template <template <class> class Derived>
struct PolicyBase {
    enum {value = IsThrow<Derived>::value};
};

template<class Ex>
struct Null : PolicyBase<Null> { };

template<class Ex>
struct Throw : PolicyBase<Throw> { } ;

template<template< class> class SomePolicy>
struct M {

  //template<class T>
  //struct D : SomePolicy<D<T>>
  //{
  //};
  static const int ist = SomePolicy<int>::value;
  typename std::enable_if<ist, void>::type value() const
  {
    cout << "Enabled";
  }

  typename std::enable_if<!ist, void>::type value() const
  {
    cout << "Disabled";
  }
};

int main()
{
    M<Null> m;
    m.value();
}

person There is nothing we can do    schedule 12.11.2010    source источник


Ответы (2)


SFINAE не работает для нешаблонных функций. Вместо этого вы можете, например. используйте специализацию (класса) или диспетчеризацию на основе перегрузки:

template<template< class> class SomePolicy>
struct M
{
    static const int ist = SomePolicy<int>::value;        
    void value() const { 
        inner_value(std::integral_constant<bool,!!ist>()); 
    }
 private:
    void inner_value(std::true_type) const { cout << "Enabled"; }
    void inner_value(std::false_type) const { cout << "Disabled"; }
};
person Georg Fritzsche    schedule 12.11.2010

Здесь нет sfinae.

После того, как известна переменная M<Null>, известна и переменная ist. Тогда std::enable_if<ist, void> тоже хорошо определен. Одна из ваших функций не определена.

SFINAE работает только для шаблонных функций. Где шаблонные функции?

Измените свой код на

template<int> struct Int2Type {}

void value_help(Int2Type<true> ) const { 
    cout << "Enabled"; 
} 

void value_help(Int2Type<false> ) const { 
    cout << "Disabled"; 
} 

void value() const { 
    return value_help(Int2Type<ist>());
}
person Alexey Malistov    schedule 12.11.2010