2010-11-12 15 views
5

Perché questo codice (valore fnc in classe M) non viene risolto dalle regole di SFINAE? Sto ottenendo un errore:Problema con SFINAE

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

Di tipo Naturalmente non è un membro, non è definito in questa ver generale enable_if, ma non è l'idea alla base di questo per abilitare questa ver di FNC se bool è vero e non lo istanziate se è falso? Potresti per favore qualcuno spiegarmelo?

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

risposta

5

SFINAE non funziona per le funzioni non-modello. Invece puoi, ad es. utilizzare specializzazione (della classe) o dispacciamento basato su sovraccarico:

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

Non v'è alcun sfinae qui.

Dopo M<Null> è nota anche la variabile ist. Quindi anche lo std::enable_if<ist, void> è ben definito. Una delle tue funzioni non è ben definita.

SFINAE funziona solo per il caso di funzioni modello. Dove sono le funzioni del modello?

modificare il codice per

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