RaenirSalazar
RaenirSalazar

Reputation: 576

Can I use an enum within an enum?

Example code:

#ifndef SPELL_ENUMS_H
#define SPELL_ENUMS_H

namespace spellEnums {
        // Cantrips
    enum LEVEL_ZERO 
    {
        enum EVOCATION 
        {
            _DANCING_LIGHTS
        };
        enum CONJURATION 
        {
            _ACID_SPLASH
        };
    };

};

So I can do stuff like LEVEL_ZERO::EVOCATION::_DANCING_LIGHTS ?

Although an alternative suggestion to have all 300+ 3.5e Dungeons and Dragon's type defined in a tight tidy easily readable and conveniently accessible would be greatly appreciated. :D

Or do I have to do lame namespacing like:

namespace LEVEL_ZERO {
        // Cantrips
        enum EVOCATION 
        {
            _DANCING_LIGHTS
        };
        enum CONJURATION 
        {
            _ACID_SPLASH
        };

};

namespace LEVEL_ONE {
        // Level one spells
        enum EVOCATION 
        {
            _FLAMING_HANDS
        };
        enum CONJURATION 
        {
            _MAGE_ARMOUR //BECAUSE JE SUIS CANADIEN le poutine eh?! 
        };

};

Or will this cause weird problems?

Upvotes: 3

Views: 141

Answers (2)

Ben S.
Ben S.

Reputation: 1143

If you really want to do this, I believe you have to use namespace and not enum. Note that the enum name isn't treated like a scope, so in the case of:

namespace LEVEL_ONE {
    // Level one spells
    enum EVOCATION 
    {
        FLAMING_HANDS
    };
    enum CONJURATION 
    {
        MAGE_ARMOUR //BECAUSE JE SUIS CANADIEN le poutine eh?! 
    };
};

The values would be referred to in the form LEVEL_ONE::FLAMING_HANDS, not LEVEL_ONE::EVOCATION::FLAMING_HANDS. You could get the desired effect with something like:

namespace LEVEL_ONE {
    // Level one spells
    namespace EVOCATION 
    {
        const int FLAMING_HANDS = 0;
        const int MAGIC_MISSILE = 1;
    };
};

I don't think that you want the values to be different types anyway, which is what you would get using enum in the way you had suggested. It seems likely that you're going to want to pass around objects of type Spell (or similar) that can refer to any spell rather than having separate types for spells from all the different schools and levels. I would probably tend toward something like:

class Spell
{
public:
    enum Magic_Type
    {
        ARCANE,
        DIVINE
    };

    enum School
    {
        EVOCATION,
        CONJURATION,
        DIVINATION,
        ...
    };

    int get_level();
    Magic_Type get_type();
    School get_school();
    void cast_on(Target &t, Board &b);  // Needs the Board to affect secondary targets.
    ...
};

Upvotes: 0

Spektre
Spektre

Reputation: 51835

I do not think that nesting enums is good approach I would use rather something like this:

enum _spell_enum 
    {
    _spell_evocation_beg=0x00000000,
    _spell_dancing_lights0,
    _spell_dancing_lights1,
    _spell_dancing_lights2,
    _spell_dark_shroud0,
    _spell_dark_shroud1,
    _spell_dark_shroud2,
    _spell_...,
    _spell_evocation_end,

    _spell_conjuration_beg=0x01000000,
    _spell_acid_splash0,
    _spell_acid_splash1,
    _spell_acid_splash2,
    _spell_acid_beam0,
    _spell_acid_beam1,
    _spell_acid_beam2,
    _spell_...,
    _spell_conjuration_end,

    _spell_teleport_beg=0x02000000,
    _spell_teleport_home,
    _spell_teleport_town_a,
    _spell_teleport_town_b,
    _spell_teleport_town_c,
    _spell_teleport_town_d,
    _spell_...,
    _spell_teleport_end,
    };

PS. if you need additional info like level and so then you can use additional tables with the needed information or use const int instead of enum and code the info into code directly (for example level could be high or low n bits) or you can group enum by level not spell type ...

also your second solution is not good because i think you need unique ID for spells and separate enums are overlapping (unless you provide start value)

Upvotes: 1

Related Questions