Como alternativa a la declaración de una clase de rasgos utilizando SFINAE, puede usarla de forma más sutil con especialización parcial.
template< typename T >
struct empty { // support class is like stripped-down enable_if
typedef void type;
};
template< class T, typename v = void > // v is always void!
struct element {
typedef typename T::value_type type;
};
template< class T, typename v >
struct element< T const, v > {
typedef typename T::value_type const type;
};
template< class T > // T in deduced context, T::element_type is SFINAE:
struct element< T, typename empty< typename T::element_type >::type > {
typedef typename T::element_type type;
};
... es posible que desee agregar otro caso para hacer element_type
const para const T
? Desafortunadamente, esto no funciona en GCC, aunque Comeau lo acepta.
template< class T >
struct element< T const, typename empty< typename T::element_type >::type > {
typedef typename T::element_type const type;
};
Código que utiliza para probar esto:
struct has_et {
typedef int element_type;
};
struct has_vt {
typedef char value_type;
};
char c;
int i;
element<has_vt>::type *cp = &c;
element<has_et>::type *ip = &i;
Para la primera parte se puede leer sobre SFINAE (google) y que está obligado a encontrar ejemplos que ilustran todo lo que necesita –
artículo de Wikipedia en SFINAE en realidad incluye un ejemplo sobre la comprobación de un typedef, escrito realmente por los tuyos. : P – GManNickG
No hay forma de detectar que el typedef, si existe, es público. El Estándar prohíbe específicamente que SFINAE trabaje con la violación del calificador de acceso. – Potatoswatter