Jump to content

  • Log In with Google      Sign In   
  • Create Account


An enum made of structs


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
12 replies to this topic

#1 studentTeacher   Members   -  Reputation: 823

Like
0Likes
Like

Posted 13 April 2013 - 01:14 AM

Hello,

 

I am trying to make an enum of structs, and was wondering how I could do that? for

example:

struct foo {
   int i;
   int j;
   Bar b;
   char c;
   //other stuff
};

enum fooEnum {
   //here, I want to make an enum of 'foo structs'. Is this possible?
}; 

 

Please help!



Sponsor:

#2 Paradigm Shifter   Crossbones+   -  Reputation: 5256

Like
0Likes
Like

Posted 13 April 2013 - 01:30 AM

No, enum values have to be of integral type.

 

Looks like a dodgy design anyway, what are you trying to do? Are you trying to make a class factory? http://en.wikipedia.org/wiki/Abstract_factory_pattern

 

There is a typeid operator, but that doesn't return integral values either.


"Most people think, great God will come from the sky, take away everything, and make everybody feel high" - Bob Marley

#3 0r0d   Members   -  Reputation: 814

Like
0Likes
Like

Posted 13 April 2013 - 01:48 AM

No you cant do that.

 

I'd also be curious to know what you're trying to accomplish with this idea.



#4 Necator   Members   -  Reputation: 239

Like
0Likes
Like

Posted 13 April 2013 - 06:24 AM

Instead of putting the data in the actual enum, you can place it in an array and index it via the enum values.

struct Foo
{
   int i;
   int j;
   Bar b;
   char c;
   //other stuff
};

enum Biz
{
	Biz_1,
	Biz_2,
	Biz_3,
	Biz_Count
};

Foo elements[Biz_Count];
elements[Biz_1].i = 10;

I believe it is as close as you can get to what you're asking for in C++.



#5 SiCrane   Moderators   -  Reputation: 9565

Like
0Likes
Like

Posted 13 April 2013 - 06:48 AM

There's also the option of const foo variables.

#6 Álvaro   Crossbones+   -  Reputation: 12928

Like
3Likes
Like

Posted 13 April 2013 - 08:25 AM

When asking this type of question [and when writing real code], it is much better to use identifiers that give a clue as to what the code is trying to do. As it is, the only valid answer is "no". The suggested workarounds are wild guesses, because we don't know enough about the situation.

#7 studentTeacher   Members   -  Reputation: 823

Like
0Likes
Like

Posted 13 April 2013 - 11:33 PM

Honestly, I'm doing this for a LONG list of attacks (like in pokemon) and I want an easier way to identify them, rather than just an index in an array or something. So for example, I have:

 

struct Move {
    char*       m_cpName;
    int         m_iID;
    MoveClass   m_class;
    Target      m_target;
    int         m_iPP;
    int         m_iAccuracy;
    int         m_iBasePower;
    int         m_iPriority;
    Type        m_type;
    int         m_iFlags;
};

 

Now, I would like to make an enum of the attacks, to make for easier lookup:

 

//create an enum of attacks, of type Move
enum Moves {
   TACKLE,
   GROWL,
   HYPER_BEAM
};

 

So when adding an attack to a creature, I'd like to just say something like this:

class Man : public Creature {
private:
//code...
   Move m1 = TACKLE;
//code...
};

 

It looks like things just won't be this easy for me though . . .

 

EDIT: By the way, I'm sorry for using general code. I guess at the time I was looking for a general answer that I might use in the future . . . but I'm now more sure that specific code might do that job better.


Edited by studentTeacher, 13 April 2013 - 11:35 PM.


#8 JTippetts   Moderators   -  Reputation: 8352

Like
2Likes
Like

Posted 13 April 2013 - 11:44 PM

If your list of attacks is really that long, you'd probably be better off storing them as data to be loaded into structures at run-time, rather than hard-coding them into the executable. That way when it comes time to tweak and balance you're not constantly re-compiling the exe every time you make a change. Look into something like YAML, JSON or XML for an idea how to do this.

#9 Sik_the_hedgehog   Crossbones+   -  Reputation: 1608

Like
0Likes
Like

Posted 14 April 2013 - 03:46 AM

Even if we ignore whether they're hardcoded or not... I'd just make an array of structs and then make the enum just a list of indices to that array (bonus because that can end up saving lots of space if you need to store these values).

 

Also the idea of not hardcoding it would break the use of enums, since at that point you'll probably need to start all other data in those files too to make it even remotely sane =P (unless you want to hardcode the moves themselves and only allow tweaking their values, rather than allowing an arbitrary amount of moves) Yes, one could argue that's the best idea, but if a large chunk of code is written already that may not be as nice.


Don't pay much attention to "the hedgehog" in my nick, it's just because "Sik" was already taken =/ By the way, Sik is pronounced like seek, not like sick.

#10 Shaquil   Members   -  Reputation: 815

Like
0Likes
Like

Posted 14 April 2013 - 09:01 AM

Hmm... I think I understand what you want. I do a similar thing with animations, if I'm getting you right. Make an enum:

 

enum AttackTypes{Tackle, Growl, HyperBeam};

 

And then make an array of Move objects and use the enum values as the indices. I feel like I might be repeating what everyone else said, or what you said you were trying to avoid, but then part of me wonders if you might've not tried that solution. Since you're using structs, you'll need a function that basically works as a constructor for each object, no? It'd look like:

 

 

void ConstructMoves(Move[]){
   for(int i = 0; i < MAX_NUM_OF_MOVES; i++){
      MoveArray[i].attackPoints = 15;
      MoveArray[i].pp = 20;
      //etc, etc
   }//end of for()
}

That would be a generic way to construct every move, though. What I would do is write an XML file with the values I need, load up the file before I start the for-loop, and then cycle through the <Move> elements, assigning the values in the element to the Move object in the array based on the index. I mean, the Move element would be something like:

<Move number = "1" attackPoints = "15" pp = "20" />


Since enums are integral values, the "number" attribute represents the value of the particular enumeration you're referring to. Since in my above example, Growl is the value 1, the above <Move> element would represent Growl. In the for-loop, you'd just check that the number value of the element and the number value of the index line up. It'd look like:

 

void ConstructMoves(Move[]){
xmlObject = loadXMLFile("Moves.xml");
  for(int i = 0; i < MAX_NUM_OF_MOVES; i++){
    while(xmlObject.CurrentElement() != NULL){
        if(xmlObject.CurrentElement().attribute("number") == i){//If this is true, we know the element matches the Move we want
           MoveArray[i].attackPoints = xmlObject.CurrentElement().attribute("attackPoints");
           //and so on
        }
        xmlObject.MoveToNextElement();//This will return NULL when there is no next element in the XML document
    }//end of while()
  }//end of for()
xmlObject.CloseFile();
}

 

Even if you don't go this route, I thought it'd be useful for future readers who might be interested in this sort of solution to your problem. I use pugixml to load and manipulate XML documents, by the way.



#11 EvincarOfAutumn   Members   -  Reputation: 327

Like
0Likes
Like

Posted 17 April 2013 - 08:07 PM

Why not just declare objects?

 

// Move.h

extern const Move
  TACKLE,
  GROWL,
  HYPER_BEAM,
  ...;

// Move.cpp

const Move TACKLE(...);
const Move GROWL(...);
const Move HYPER_BEAM(...);

 

If you need these in a table (e.g., to refer to them by integer ID), then you can build that separately.



#12 phil_t   Crossbones+   -  Reputation: 3260

Like
0Likes
Like

Posted 18 April 2013 - 11:18 AM

Yeah, I don't understand the need for enums here. They could just be global constants in your case.



#13 jellyfishchris   Members   -  Reputation: 300

Like
0Likes
Like

Posted 18 April 2013 - 07:21 PM

I did a little shell for you to look at and fill in yourself. Consider using tinyXML to load XML. (No idea if any of this compiles, as it was only to show you what to do)

 

 

struct Move{    
char*       m_cpName;    
int         m_iID;    
MoveClass   m_class;    
Target      m_target;    
int         m_iPP;    
int         m_iAccuracy;    
int         m_iBasePower;    
int         m_iPriority;    
Type        m_type;    
int         m_iFlags;};
enum 
Moves{   TACKLE,   GROWL,   HYPER_BEAM};
class Moves{
public: bool LoadMoves(std::string filename) {  
//LoadXML file  
//As you load them you can tell in the XML I do <Move type = "1">  
//this means that this move is tackle because in the enums its the first value  
//Load in all of the related data to the move.  
return true; 
} 
Move* GetMove(int type) {  
//checking and return the move  
return nullptr; 
}
private:  
std::vector<Move*> m_listOfMoves;
};





<?xml version = "1.0"?>
<Moves>
 <Move type = "1">
  <Name>Tackle<Name/>
  <ID>1</ID>
  <PP>3</PP>
 </Move>
</Moves>


 


Edited by jellyfishchris, 18 April 2013 - 07:21 PM.





Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS