Может ли enum-класс быть вложенным?

Можно ли это сделать?

enum A
{
enum B
{
SOMETHING1,
SOMETHING2
};

enum C
{
SOMETHING3,
SOMETHING4
};
};

Если нет, есть ли альтернативное решение?

Цель этого вопроса: Хотите / должны быть в состоянии сделать что-то вроде этого:

enum class ElementaryParticleTypes
{

enum class MATTER
{
enum class MESONS
{
PI
};

enum class BARYONS
{
PROTON,
NEUTRON
};

enum class LEPTONS
{
ELECTRON
};
};

enum class ANTI_MATTER
{
enum class ANTI_MESONS
{
ANTI_PI
};

enum class ANTI_BARYONS
{
ANTI_PROTON
ANTI_NEUTRON
};

enum class ANTI_LEPTONS
{
POSITRON
};
};

};

Хотите использовать строго типизированные возможности.

5

Решение

нет, они не могут быть вложены таким образом. Фактически, любой компилятор отклонил бы это.

Если нет, есть ли альтернативное решение?

Это в основном зависит от того, чего вы пытаетесь достичь (решение какой проблемы?). Если ваша цель — написать что-то вроде A::B::SOMETHING1, вы можете просто определить их в пространстве имен следующим образом:

namespace A
{
enum B
{
SOMETHING1,
SOMETHING2
};

enum C
{
SOMETHING3,
SOMETHING4
};
}
9

Другие решения

Видя, что в данном конкретном случае перечисления вряд ли будут часто меняться, вы можете пойти на:

namespace ParticleTypes {
namespace Matter {
enum Mesons {
Pi
};

enum Baryons {
Proton = Pi + 1,
Neutron
};

enum Leptons {
Electron = Neutron + 1
};
}

namespace AntiMatter {
enum AntiMesons {
AntiPi = Matter::Electron + 1
};

// ...
}
}

Я удивляюсь, однако, почему вы хотите разные enum типы для разных типов частиц. У вас есть функции, которые принимают аргумент типа Mesonsно не типа Leptons? Если нет, и все ваши функции принимают любую из частиц, то используйте один enum — и предпочтительно, сбрасывать длинные префиксы с именами значений, таких как MATTER_MESONS_, MATTER_BARYONS_ и т.п.

3

MESONS pi = PI();
MATTER mat = pi;
assert (pi == mat);

Вы не против немного магии шаблонов C ++ 11?

template <typename T, typename... L>
struct is_defined_in : std::false_type {};

template <typename T, typename U, typename... L>
struct is_defined_in<T, U, L...> : is_defined_in<T, L...> {};

template <typename T, typename... L>
struct is_defined_in<T, T, L...> : std::true_type {};

template <int ID> struct helper {
friend bool operator==(helper a, helper b)
{ return a.id == b.id; }
friend bool operator!=(helper a, helper b)
{ return a.id != b.id; }

int id=ID;
};
template <typename... B> struct category {
int id;

template <typename T,
typename = typename std::enable_if<is_defined_in<T, B...>::value>::type>
category(T t) : id(t.id) {}

friend bool operator==(category a, category b)
{ return a.id == b.id; }
friend bool operator!=(category a, category b)
{ return a.id != b.id; }
};

enum class ElementaryParticleTypesID
{ PI, PROTON, NEUTRON, ELECTRON };

struct PI       : helper<(int)ElementaryParticleTypesID::PI> {};
struct PROTON   : helper<(int)ElementaryParticleTypesID::PROTON> {};
struct NEUTRON  : helper<(int)ElementaryParticleTypesID::NEUTRON> {};
struct ELECTRON : helper<(int)ElementaryParticleTypesID::ELECTRON> {};

using MESONS = category<PI>;
using BARYONS = category<PROTON, NEUTRON>;
using LEPTONS = category<ELECTRON>;

using MATTER = category<MESONS, BARYONS, LEPTONS>;

(the static_assert в настоящее время не работает за пределами двух иерархий, но это можно добавить, если хотите)

0

Нет, нет способа сделать это без определения всего в длинном списке внутри одного перечисления.

enum class A{
PARTICLE_MATTER_BARYON_PROTON,
PARTICLE_MATTER_BARYON_NEUTRON,
PARTICLE_ANTIMATTER_BARYON_PROTON // etc
};

Если это не имеет смысла для вас, то вы, конечно, физик.

Я принимаю это как ответ, чтобы не допустить дальнейших уведомлений от stackoverflow с просьбой принять ответ.

-2
По вопросам рекламы [email protected]