Can enum class be nested?

后端 未结 4 1397
执笔经年
执笔经年 2021-02-14 17:33

Can this be done?

enum A
{
    enum B
    {
        SOMETHING1,
        SOMETHING2
    };

    enum C
    {
        SOMETHING3,
        SOMETHING4
    };
};


        
相关标签:
4条回答
  • 2021-02-14 18:09

    Seeing that in this particular case, the enumerations aren’t likely to change often, you could go for:

    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
            };
    
            // ...
        }
    }
    

    I do wonder, however, why you want different enum types for different types of particles. Do you have functions which accept an argument of type Mesons, but not of type Leptons? If not, and all your functions accept any of the particles, then use a single enum – and preferably, drop the long prefixes to the names of the values like MATTER_MESONS_, MATTER_BARYONS_ etc.

    0 讨论(0)
  • 2021-02-14 18:22

    No, they cannot be nested that way. In fact, any compiler would reject it.

    If not is there an alternative solution?

    That mostly depends on what you are trying to achieve (solution to what problem?). If your goal is to be able to write something like A::B::SOMETHING1, you could just define them within a namespace, this way:

    namespace A
    {
        enum B
        {
            SOMETHING1,
            SOMETHING2
        };
    
        enum C
        {
            SOMETHING3,
            SOMETHING4
        };     
    }
    
    0 讨论(0)
  • 2021-02-14 18:22
    MESONS pi = PI();
    MATTER mat = pi;
    assert (pi == mat);
    

    Do you mind a little C++11 template magic?

    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 currently doesn't work beyond two hierarchies, but this can be added if you want to)

    0 讨论(0)
  • 2021-02-14 18:32

    No, there is no way of doing this without defining everything in a long list inside one enum.

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

    If this doesn't make sense to you, then you are surely a physicist.

    I am accepting this as the answer to stop further notifications from stackoverflow asking me to accept an answer.

    0 讨论(0)
提交回复
热议问题