2010-11-12 13 views
5

¿Por qué este código (valor de fnc en la clase M) no se resuelve con las reglas de SFINAE? Estoy consiguiendo un error:Problema con SFINAE

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

Por supuesto tipo no es miembro, no se define en esta ver general de enable_if pero no es la idea detrás de esto para habilitar esta ver de FNC si bool es cierto y no lo instancia si es falso? ¿Podría por favor que alguien me explique eso?

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

Respuesta

5

SFINAE no funciona para funciones que no son de plantilla. En cambio, puedes, por ejemplo, uso especialización (de la clase) o despacho basado en sobrecarga:

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

Hay sin sfinae aquí.

Después de conocerse M<Null>, también se conoce la variable ist. Luego, std::enable_if<ist, void> está bien definido también. Una de sus funciones no está bien definida.

SFINAE funciona solo para el caso de funciones de plantilla. ¿Dónde están las funciones de la plantilla?

cambiar el código para

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