Как избежать конфликтов имен для двух значений enum с тем же именем в С++?
Перечисления в С++ имеют одну серьезную проблему: вы не можете иметь одно имя в двух разных перечислениях, например:
enum Browser
{
None = 0,
Chrome = 1,
Firefox = 2
}
enum OS
{
None = 0,
XP = 1,
Windows7 = 2
}
Итак, каков наилучший способ справиться с этой проблемой в этом примере?
Ответы
Ответ 1
В С++ 03 вы можете заключить enum
внутри a struct
:
struct Browser
{
enum eBrowser
{
None = 0,
Chrome = 1,
Firefox = 2
};
};
В С++ 11 сделайте его enum class
:
enum class Browser
{
None = 0,
Chrome = 1,
Firefox = 2
};
В С++ 03 namespace
также можно обернуть, но лично я считаю, что обертка struct
/class
лучше, потому что namespace
более шире. например.
// file1.h
namespace X
{
enum E { OK };
}
// file2.h
namespace X
{
enum D { OK };
}
Ответ 2
Один параметр состоит в том, чтобы поместить каждое перечисление в другое пространство имен:
namespace Foo {
enum Browser {
None = 0,
Chrome = 1,
Firefox = 2
}
}
namespace Bar {
enum OS {
None = 0,
XP = 1,
Windows7 = 2
}
}
Лучшим вариантом, если он доступен в вашем компиляторе, является использование классов С++ 11 enum:
enum class Browser { ... }
enum class OS { ... }
См. здесь для обсуждения классов enum.
Ответ 3
Либо оберните их в пространствах имен или в классах:
namespace Browser {
enum BrowserType
{
None = 0,
Chrome = 1,
Firefox = 2
}
}
namespace OS {
enum OSType {
None = 0,
XP = 1,
Windows7 = 2
}
}
Ответ 4
Вы можете использовать enum class
(скопированные перечисления), который поддерживается в С++ 11 вверх. Он строго типизирован и указывает, что каждый тип enum
отличается.
Browser::None != OS::None
enum class Browser
{
None = 0,
Chrome = 1,
Firefox = 2
}
enum class OS
{
None = 0,
XP = 1,
Windows7 = 2
}
Ответ 5
Как насчет использования scope или unscoped enumeration? С++ 11 теперь предлагает облачное перечисление. Примером может служить:
enum class Browser : <type> {
};
enum class OS : <type> {
};
Доступ к перечисленным типам осуществляется через объект обозревателя или объект ОС.