Обычный способ эмулировать перечисления с областью действия до C ++ 11 - объявлять перечисление без сферы действия в объявлении класса:
#include <iostream>
struct Color {
enum MyColor {
kRed,
kBlue
};
};
int main() {
const Color::MyColor color = Color::kRed;
if (color == Color::kRed)
{
std::cout << "red" << std::endl;
}
}
или, как незначительный вариант, для некоторой краткости на возможная стоимость некоторой путаницы (то есть на сайте использования: «как соотносятся MyColor
и Color
?»):
#include <iostream>
struct Color {
enum MyColorImpl {
kRed,
kBlue
};
};
typedef Color::MyColorImpl MyColor;
int main() {
const MyColor color = Color::kRed;
if (color == Color::kRed)
{
std::cout << "red" << std::endl;
}
}
Конечно, вы также можете использовать подход к определению пространства имен, показанный в ваш вопрос, но он связан с потенциальной проблемой: пространство имен может быть расширено в другом месте вашей кодовой базы, что, в свою очередь, может привести к неожиданному ( ожиданиям разработчика ) поведению; например, ваше эмулированное перечисление scoped-enum может начать вести себя как объединение нескольких различных перечислений, не относящихся к области.
#include <iostream>
namespace color {
enum MyColor {
kRed,
kBlue
};
}
namespace color {
enum CarColor {
kAbsolutelyNotRed
};
}
int main() {
const color::MyColor color = color::kRed;
// At best, a -Wenum-compare warning.
if (color == color::kAbsolutelyNotRed)
{
// At worst, a critical logical fault.
std::cout << "absolutely not red (ups, actually red)" << std::endl;
}
}