Pregunta sobre typetraits, c++, c++11, enums, metaprogramming – ¿Es posible determinar si un tipo es un tipo de enumeración con alcance?

14

¿Hay un rasgo de tipo, o es posible escribir un rasgo de tipois_scoped_enum<T> tal que

SiT es una enumeración de ámbito,is_scoped_enum<T>::value estrue ySiT es cualquier otro tipo,is_scoped_enum<T>::value Es falso
@ R.MartinhoFernandes: Ha; que se ve familiar :-)cxxreflect.codeplex.com/SourceControl/changeset/view/… (buscarCXXREFLECT_GENERATE_SCOPED_ENUM_OPERATORS) Desafortunadamente, Visual C ++ no soportaconstexpr, lo que hace que las enumeraciones de ámbito sean bastante dolorosas para las banderas, pero al menos con los operadores esmejor. Aunque me gusta el uso de tus rasgos. Para las banderas, he estado usando unflags<T> Tipo de clase para envolver la enumeración. James McNellis
@Xeo: Estoy sobrecargando los operadores bitwise para un conjunto de tipos de enumeración de ámbito. James McNellis
@Nawaz: una enumeración de alcance es lo que unenum class Se llama en C ++ 11, sí. James McNellis

Tu respuesta

1   la respuesta
25

Pienso probando si es una enumeración.y no implícitamente convertible al tipo subyacente debe hacer el truco.

template <typename T, bool B = std::is_enum<T>::value>
struct is_scoped_enum : std::false_type {};

template <typename T>
struct is_scoped_enum<T, true>
: std::integral_constant<bool,
    !std::is_convertible<T, typename std::underlying_type<T>::type>::value> {};
@Excelcius Es peor que la posibilidad de obtener un error o no: usarstd::underlying_type un tipo que no es enumeración es un comportamiento indefinido, que no requiere diagnóstico, por lo que el compilador no necesita reportar el uso indebido, que luego le da a su programa UB. No observé implementaciones comunes, pero supongo que el Estándar permite que UB facilite la implementación en casos de uso válidos. underscore_d
@KennyTM buen punto. Editado R. Martinho Fernandes
@James Oh, oops. R. Martinho Fernandes
Me gustaría agregar (porque he tenido este problema): este rasgo también podría implementarse como unousing declaración (alias de plantilla) como se sugiereaquí, pero entoncesstd::underlying_type serán evaluados para todos los tipos, y algunos compiladores generan un error al usarunderlying_type con tipos distintos de enumeración (sin SFINAE). Así que esta solución es probablemente la mejor. Excelcius

Preguntas relacionadas