![]() |
| | #1 |
| Registered User Join Date: Nov 2006
Posts: 502
| How to map enums to their string representation globaly? in my programs I often use enums for integer constants: Code:
// directions.h
enum Directions
{
west=1,
south=2,
east=3,
nord=4
};
No I sometimes come to the point there I want to display the enum value, so I have to map them somewhere to their string representation. best thing I came up with yet is to have a std::map<int, string> class memeber in each class what needs the enum-string-representation. the map is filled in the classes ctor. now that's not a very clear solution because of the redundant code. I wonder if their is a better solution to this problem or some well known idiom? Thanks for your ideas! |
| pheres is offline | |
| | #2 |
| Ethernal Noob Join Date: Nov 2001
Posts: 1,888
| either that or a switch case block. |
| indigo0086 is offline | |
| | #3 |
| Massively Single Player Join Date: May 2007 Location: Buffalo, NY
Posts: 141
| Make a map<Directions, string> that contains all the values, and then: Code: ostream &operator << (ostream &out, Directions d)
{
out << DirectionMap[d];
return out;
}
__________________ There is no greater sign that a computing technology is worthless than the association of the word "solution" with it. |
| AverageSoftware is offline | |
| | #4 |
| Tropical Coder Join Date: Mar 2005 Location: Cayman Islands
Posts: 503
| I think using a map is a bit overkill. Here is what I typically do: Code: #include <iostream>
#include <string>
enum Directions
{
west=1,
south, // i removed the rest since it's sequential
east,
north, // changed spelling
};
std::string direction2string[] ={"","West", "South", "East", "North"}; // added dummy value to skip 0
int main ()
{
std::cout << direction2string[west] <<std::endl;
std::cout << direction2string[south] <<std::endl;
}
__________________ SWinC - Simple Windows Class |
| Darryl is offline | |
| | #5 |
| Registered User Join Date: Nov 2006
Posts: 502
| Thanks for you replies. But my question wasn't about the output in the first place (it's displayed in a gui most of the time). the thing that bothers me is that the map<int, string> or the string array like in Darryls explanation has to be built in every single class what wants "to know" the string representation of the enum values. So if I have three classes I have 3 times the same bunch of code in the ctor. and if the enum changes, I have to change 3 classes. and if I forgot one, or switch the sequence of two enum values in one class by accident I run into trouble. So I'm looking for a more central place to keep that string representation data. Sorry for making this not clear enough in my first post (I'm not a natural speaker). |
| pheres is offline | |
| | #6 |
| Registered User Join Date: Jan 2005
Posts: 7,137
| I would make a header file with an enum and a global function declaration (perhaps in a namespace if you are using namespaces). The function would take the enum as a parameter and return a string. Then in a source file define the function to use your map or array or switch to return the proper string. If you use the map or array solution, define it in that source file in an unnamed namespace so it is local to that file. This way the other code can use the enum and call the function, yet all that code will be written and maintained in one place. |
| Daved is offline | |
| | #7 |
| C++ Witch Join Date: Oct 2003 Location: Singapore
Posts: 10,365
| In Effective C++, Third Edition, Item 18, Scott Meyers suggests creating a full fledged class for a case that seems like the one you are facing. A possible adaptation of his suggestion would be: Code: class Direction
{
public:
static Direction west()
{
return Direction(1);
}
static Direction south()
{
return Direction(2);
}
static Direction east()
{
return Direction(3);
}
static Direction north()
{
return Direction(4);
}
// ... other member functions ...
private:
// prevent creation of new Direction values
explicit Direction(int d) : direction(d) {}
// Direction specific data
int direction;
};
__________________ C + C++ Compiler: MinGW port of GCC Build + Version Control System: SCons + Bazaar Look up a C/C++ Reference and learn How To Ask Questions The Smart Way |
| laserlight is online now | |
| | #8 | |
| Tropical Coder Join Date: Mar 2005 Location: Cayman Islands
Posts: 503
| Quote:
**EDIT** Just looking at Daved's post, take my direction2string, wrap it in a function with the protype in the header Code: In your header
direction.h
enum Directions
{
west=1,
south=2,
east=3,
nord=4
};
std::string dir2str(Directions d);
in your implementation
direction.cpp
std::string dir2str(Directions d)
{
std::string direction2string[] ={"","West", "South", "East", "North"};
return direction2string[d];
}
__________________ SWinC - Simple Windows Class Last edited by Darryl; 07-06-2007 at 02:57 PM. Reason: Read Daved's post | |
| Darryl is offline | |
| | #9 |
| C++ Witch Join Date: Oct 2003 Location: Singapore
Posts: 10,365
| Actually, is there any good reason to start the numbering from 1 instead of 0 for the case of the enum? Even in my suggested solution the actual values of the numbers do not really matter, and starting from 0 will make using an array of names easier. The downside to using an enum as opposed to a class is that it is less typesafe, methinks.
__________________ C + C++ Compiler: MinGW port of GCC Build + Version Control System: SCons + Bazaar Look up a C/C++ Reference and learn How To Ask Questions The Smart Way |
| laserlight is online now | |
| | #10 |
| Tropical Coder Join Date: Mar 2005 Location: Cayman Islands
Posts: 503
| I don't think it's any less typesafe than a class and possibly more, because the values are constants.
__________________ SWinC - Simple Windows Class |
| Darryl is offline | |
| | #11 | |
| C++ Witch Join Date: Oct 2003 Location: Singapore
Posts: 10,365
| Quote:
What I had in mind was more of the Code: int s = south;
__________________ C + C++ Compiler: MinGW port of GCC Build + Version Control System: SCons + Bazaar Look up a C/C++ Reference and learn How To Ask Questions The Smart Way | |
| laserlight is online now | |
| | #12 |
| l'Anziano Join Date: Aug 2001
Posts: 2,573
| Basically I kind of echo what laserlight has been saying. Make a class, and then that class may be used by any other class in your project. Even if you don't want to make it an entire class, I would still take that code out and put it in a separate "common" header file that all your classes have access to. Most projects usually have some type of file called "common.h" or "shared.h" which is just a file that has tons of stuff in it that everything wants to use. By the way, I noticed that in your first post, you spelled "north" as "nord". What country do you come from? sei italiano? |
| DavidP is offline | |
| | #13 |
| CSharpener Join Date: Oct 2006
Posts: 5,242
| And you class may also want to load strings from resources - so it will be easier later to switch to another language
__________________ If I have eight hours for cutting wood, I spend six sharpening my axe. |
| vart is offline | |
| | #14 |
| Registered User Join Date: Nov 2006
Posts: 502
| Thank you all for that inspiring discussion! That are two very reasonable solutions so far. I'm still not shure what to prefer: laserlights class with the static functions or Darryls global function. I'll probably try the class, because there I have to "touch" every value only one time. Thing is I have some enums here with more than 100 values in it. So I better write a converter program. finally a reason to learn about boost::regex ![]() two questions remains to me. first Code: std::string dir2str(Directions d)
{
std::string direction2string[] ={"","West", "South", "East", "North"};
return direction2string[d];
}
Code: std::map<int,string> directions = . . . ; "nord" comes more from the country in the north of italy |
| pheres is offline | |
| | #15 |
| Tropical Coder Join Date: Mar 2005 Location: Cayman Islands
Posts: 503
| 1st - No you can't initialize maps with an initialization list. As a matter of fact, you can't with any of the standard template containers which is an issue I think they are addressing in the new standard. Now, here's my arguements for enums. 1. Ease of implemenation - You'd have to write a function for each "value" you want which as you've already stated, with hundreds could be a lot. 2. Maintenance and error proneness. - Because you have to assign each integer value, a class with hundreds of values is more prone to duplicates, either by careless assignment or typo whereas enum value assignment is automatic. Inserting a value in between other values would be quite difficult for the static functions. 3. Efficiency - Every time you change a direction, with the static method you create a new temp object which calls a constructor, destructor and assignment operator. That's all I can think of now. :-)
__________________ SWinC - Simple Windows Class Last edited by Darryl; 07-08-2007 at 09:22 AM. |
| Darryl is offline | |
![]() |
| Thread Tools | |
| Display Modes | |
|
Similar Threads | ||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| String, Pair and Map Problem | dream_noir | C++ Programming | 3 | 02-19-2009 07:46 PM |
| String Class | BKurosawa | C++ Programming | 117 | 08-09-2007 01:02 AM |
| We Got _DEBUG Errors | Tonto | Windows Programming | 5 | 12-22-2006 05:45 PM |
| Message class ** Need help befor 12am tonight** | TransformedBG | C++ Programming | 1 | 11-29-2006 11:03 PM |
| can anyone see anything wrong with this code | occ0708 | C++ Programming | 6 | 12-07-2004 12:47 PM |