Lección 16 · 16 de 20
Espacios de nombres y enum class · C++
Organice el código de C++ con namespaces, alias y using, y use enum class para estados con nombre y seguros: los pasos de un pedido.

Un espacio de nombres (namespace) agrupa nombres para que no choquen con los de otras partes del programa o de otras bibliotecas: shop::label no se confunde con ningún otro label. Es lo que hace std:: con toda la biblioteca estándar. Desde fuera se usa el nombre completo, con ::.
Desde C++17, namespace shop::tax abre un espacio anidado en una sola línea, y namespace tx = shop::tax; crea un alias más corto. using shop::OrderStatus; trae solo ese nombre al bloque de main, que es más prudente que traer un espacio entero con using namespace.
`enum class` define un tipo con valores con nombre. A diferencia del enum clásico, sus nombres van dentro del tipo (OrderStatus::Paid) y no se convierten solos en enteros: status == 2 no compilaría. Para pasar al paso siguiente hay que convertir a propósito, con static_cast<int> y de vuelta con static_cast<OrderStatus>; los valores empiezan en 0, así que «shipped» es el paso 2.
También se puede elegir el tipo subyacente: Priority : char guarda cada valor en un carácter, 'L' o 'H'. El switch de label cubre todos los estados; si se añade uno nuevo y se olvida aquí, -Wall avisa. constexpr double vat es una constante que el compilador conoce de antemano, como verá en la lección 19.
Código · main.cpp
#include <iostream>#include <string>namespace shop { // enum class: scoped names that do not turn into int on their own. enum class OrderStatus { Pending, Paid, Shipped, Delivered }; enum class Priority : char { Low = 'L', High = 'H' }; // chosen underlying type std::string label(OrderStatus s) { switch (s) { case OrderStatus::Pending: return "pending"; case OrderStatus::Paid: return "paid"; case OrderStatus::Shipped: return "shipped"; case OrderStatus::Delivered: return "delivered"; } return "unknown"; }}namespace shop::tax { // a nested namespace (C++17 syntax) constexpr double vat = 0.21; double withVat(double net) { return net * (1 + vat); }}namespace tx = shop::tax; // a shorter aliasint main() { using shop::OrderStatus; // bring in just this one name OrderStatus status = OrderStatus::Paid; std::cout << "Order is " << shop::label(status) << "\n"; status = static_cast<OrderStatus>(static_cast<int>(status) + 1); // next step std::cout << "Now it is " << shop::label(status) << " (step " << static_cast<int>(status) << ")\n"; std::cout << "Priority code: " << static_cast<char>(shop::Priority::High) << "\n"; std::cout << "120 EUR + VAT = " << tx::withVat(120) << " EUR\n";}Salida · c++ -std=c++17 main.cpp -o main && ./main
Order is paid Now it is shipped (step 2) Priority code: H 120 EUR + VAT = 145.2 EUR
Para recordar
namespace nombre { ... }agrupa código; se usa comonombre::cosa.namespace a::banida ynamespace x = a::b;crea un alias.using a::cosa;trae un solo nombre; eviteusing namespaceen cabeceras.enum classno se mezcla con enteros sin unstatic_cast.enum class E : charelige el tipo con el que se guarda.
Ejercicio
Añada el estado Cancelled a OrderStatus, compile para ver el aviso del switch y complete label para que devuelva "cancelled".