2014-09-02 9 views
5

Esistono diversi modi per implementare un modello has_type<T> che deduce se T ha una classe nidificata o typedef denominata type. cioètemplate_type restituisce true per struct type {};

namespace detail { 
    template<typename> struct tovoid { typedef void type; }; 
} 

template<typename T, typename = void> struct has_type 
    : std::false_type { }; 
// this one will only be selected if C::type is valid 
template<typename C> struct has_type<C, typename detail::tovoid<typename C::type>::type> 
    : std::true_type { }; 

O

template <typename C> char test_for_type(...) { return '0'; } 
template <typename C> double test_for_type(typename C::type const *) { return 0.0; } 

template <typename T> struct has_type 
{ 
    static const bool value = sizeof(test_for_type<T>(0)) == sizeof(double); 
}; 

comunque in entrambi i casi, è has_type<type>::valuetrue per questa classe:

struct type 
{ 
}; 

Ora il sopra type non avere un altro type annidato all'interno di esso, ma ha un costruttore type::type().

Ma il costruttore dovrebbe "attivare" i controlli per il tipo annidato? O è un bug del compilatore? (Mi piacerebbe pensare che typename type::type non si applica a un costruttore e/o che non si poteva prendere un puntatore a un costruttore, come ad esempio quello che sarebbe prodotta dal secondo metodo di prova:. typename type::type const *

?

risposta

5

il nome di una classe è "iniettato" nel campo di applicazione della classe, in modo type::type è davvero il nome di un tipo, ed è dello stesso tipo di ::type.

+1

Ah, è vero. e credo 'struct type {struct type {};}; 'non è valido, così come' struct type {typedef int type;}; '. Che risponde alla mia domanda successiva - come gestire questo caso (se davvero lo volessi). di ch ecking se T è denominato type, che non dovrebbe essere troppo difficile. – tony

+0

e grazie per la rapida risposta! – tony

+0

@tony Più rigido e meno portatile di quanto si pensi: http://stackoverflow.com/q/1055452/501250 – cdhowie

Problemi correlati