uniones tipos imprimir español enumerados enum ejemplo crear c++ enums c++11 enum-class

c++ - tipos - typedef enum c ejemplo



¿Cómo puedo generar el valor de una clase enum en C++ 11? (4)

(No puedo comentar aún). Sugeriría las siguientes mejoras a la ya gran respuesta de James McNellis:

template <typename Enumeration> constexpr auto as_integer(Enumeration const value) -> typename std::underlying_type<Enumeration>::type { static_assert(std::is_enum<Enumeration>::value, "parameter is not of type enum or enum class"); return static_cast<typename std::underlying_type<Enumeration>::type>(value); }

con

  • constexpr : permitiéndome usar un valor de miembro enum como tamaño de matriz en tiempo de compilación
  • static_assert + is_enum : para ''asegurar'' en tiempo de compilación que la función hace algo. con enumeraciones solamente, como se sugiere

Por cierto, me estoy preguntando: ¿por qué debería usar la enum class cuando quisiera asignar valores numéricos a mis miembros enum? Teniendo en cuenta el esfuerzo de conversión.

Quizás, entonces, volvería a la enum ordinaria como sugerí aquí: ¿Cómo usar las enumeraciones como banderas en C ++?

Otro sabor (mejor) sin static_assert, basado en una sugerencia de @TobySpeight:

template <typename Enumeration> constexpr std::enable_if_t<std::is_enum<Enumeration>::value, std::underlying_type_t<Enumeration>> as_number(const Enumeration value) { return static_cast<std::underlying_type_t<Enumeration>>(value); }

¿Cómo puedo generar el valor de una enum class en C ++ 11? En C ++ 03 es así:

#include <iostream> using namespace std; enum A { a = 1, b = 69, c= 666 }; int main () { A a = A::c; cout << a << endl; }

en c ++ 0x este código no compila

#include <iostream> using namespace std; enum class A { a = 1, b = 69, c= 666 }; int main () { A a = A::c; cout << a << endl; } prog.cpp:13:11: error: cannot bind ''std::ostream'' lvalue to ''std::basic_ostream<char>&&'' /usr/lib/gcc/i686-pc-linux-gnu/4.5.1/../../../../include/c++/4.5.1/ostream:579:5: error: initializing argument 1 of ''std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&&, const _Tp&) [with _CharT = char, _Traits = std::char_traits<char>, _Tp = A]''

compilado en Ideone.com


A diferencia de una enumeración sin ámbito, una enumeración con ámbito no es implícitamente convertible a su valor entero. Necesitas convertirlo explícitamente a un número entero usando un molde:

std::cout << static_cast<std::underlying_type<A>::type>(a) << std::endl;

Es posible que desee encapsular la lógica en una plantilla de función:

template <typename Enumeration> auto as_integer(Enumeration const value) -> typename std::underlying_type<Enumeration>::type { return static_cast<typename std::underlying_type<Enumeration>::type>(value); }

Usado como:

std::cout << as_integer(a) << std::endl;


Es posible obtener su segundo ejemplo (es decir, el que utiliza una enumeración de ámbito) para trabajar con la misma sintaxis que las enumeraciones sin ámbito. Además, la solución es genérica y funcionará para todas las enumeraciones con ámbito, en comparación con la escritura del código para cada enum con ámbito (como se muestra en la answer proporcionada por ).

La solución es escribir una función operator<< genérica del operator<< que funcionará para cualquier enumeración del alcance. La solución emplea SFINAE través de std::enable_if y es la siguiente.

#include <iostream> #include <type_traits> // Scoped enum enum class Color { Red, Green, Blue }; // Unscoped enum enum Orientation { Horizontal, Vertical }; // Another scoped enum enum class ExecStatus { Idle, Started, Running }; template<typename T> std::ostream& operator<<(typename std::enable_if<std::is_enum<T>::value, std::ostream>::type& stream, const T& e) { return stream << static_cast<typename std::underlying_type<T>::type>(e); } int main() { std::cout << Color::Blue << "/n"; std::cout << Vertical << "/n"; std::cout << ExecStatus::Running << "/n"; return 0; }


#include <iostream> #include <type_traits> using namespace std; enum class A { a = 1, b = 69, c= 666 }; std::ostream& operator << (std::ostream& os, const A& obj) { os << static_cast<std::underlying_type<A>::type>(obj); return os; } int main () { A a = A::c; cout << a << endl; }