Thread: Enumerators as strings

  1. #1
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446

    Enumerators as strings

    Is there a better way to extract enumerators names, other than using a vector<string> to match the enumeration?

    Code:
    enum ESomeEnum { Opened, Closed, Locked };
    
    vector<std::string> SomeEnumStrings(3);
    SomeEnumStrings[0] = "Opened");
    SomeEnumStrings[1] = "Closed");
    SomeEnumStrings[2] = "Locked");
    
    int main() {
        CDoor myDoor;
        myDoor.setStatus(Closed);
    
        std::cout << "The door is " << SomeEnumStrings[myDoor.getStatus()] << "." << std::endl;
    }
    Last edited by Mario F.; 07-19-2006 at 10:04 AM.
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  2. #2
    Registered User
    Join Date
    Aug 2005
    Posts
    1,267
    I think map would be better than vector.

  3. #3
    Registered User
    Join Date
    Nov 2001
    Posts
    1,348
    make sure you initialize enum

    Kuphryn

  4. #4
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >I think map would be better than vector.
    A map is better when the index is a string, but in this case it seems that the index is an integer. The only real issue is that the enum and vector have to keep the same order, which could be an annoying maintenance problem that a map handles automatically. Then again, the contiguous memory of a vector could be a deciding factor, as could the fact that a map is a more complicated data structure and there could be performance or footprint issues.

    That said, I would probably use a map.
    My best code is written with the delete key.

  5. #5
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    You could do it the Mozilla way:

    some_include.h:
    Code:
    LOCAL_ENUM_VALUE_MACRO(Opened)
    LOCAL_ENUM_VALUE_MACRO(Closed)
    LOCAL_ENUM_VALUE_MACRO(Locked)
    user.cpp:
    Code:
    #define LOCAL_ENUM_VALUE_MACRO(v) v,
    enum ESomeEnum {
    #include "some_include.h"
    ESEDU_COUNT
    };
    #undef LOCAL_ENUM_VALUE_MACRO
    
    #define LOCAL_ENUM_VALUE_MACRO(v) #v,
    const char *const ESomeEnumStrings[] = {
    #include "some_include.h"
    }
    #undef LOCAL_ENUM_VALUE_MACRO
    Not necessarily pretty, but it works, and it keeps the two in sync.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  6. #6
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    A map it will be. Thanks everyone

    On a not so related note... why am I not being able to create a vector at the global scope?
    Code:
    #include <vector>
    
    std::vector<int> myVector(3);
    myVector[0] = 1; // error
    myVector[1] = 1; // error
    myVector[2] = 1; // error
    
    int main() {
     /* ... */
    }
    I get the following error at every assignment attempt:
    expected constructor, destructor, or type conversion before '=' token
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  7. #7
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    You can create the vector, but you can't have code outside of any function that assigns values to its data. If you want to initialize all the values to 1, you would use std::vector<int> myVector(3, 1). If you want more complex assignment, you'll have to put into a function.

    >> make sure you initialize enum
    What do you mean?

  8. #8
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    What could be considered good norm to do this?

    Declare the global on my utils header file and define a init() function where these globals are defined?

    Code:
    // utils.h
    #include <vector>
    extern std::vector<int> myGlobal;
    
    //utils.cpp
    #include "utils.h"
    
    void init() {
        std::vector<int> myGlobal(3)
        myGlobal[0] = 1;
        /* ... */
    }
    /* ... */
    
    //main.cpp
    #include "utils.h"
    
    int main() {
         init();
        /* ... */
    }
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  9. #9
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    Why do you need to have a global vector? Normally, it would be part of a class that does the initialization in the constructor.

  10. #10
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    The vector (in fact it will be a few maps) will hold strings. Much like what is provided with a resource file. Some maps will map to enumerators, but the 3 biggest ones will provide the support for a series of random generated item names (ala Diablo II item generation); "brilliant longsword of maiming", "crude helm of Yark", ....
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  11. #11
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    Ok. So put it in a class and do the initalization in the constructor. If you still want the data to be global, you can make a global instance of the class.

  12. #12
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    Ok... sorry to bother you Daved. I'm having a blond day...

    But you mean putting each map inside his own class?
    I wouldn't need more than one instance of this class. Or is that you mean the map would be a static member of the class and there wouldn't be any need to create instances to use it?
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  13. #13
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    I think that you should create your global vector, do the initializing in a function, and then work with that vector throughout the program. You just need a list of stuff right now. Right?
    Code:
    vector<string> PCEquipment;
    
    void setup_equipment() {
       if (PCEquipment.empty()) {
          PCEquipment.push_back( string("brilliant longsword of maiming") );
          PCEquipment.push_back( string("crude helmet of Yark") );
          PCEquipment.push_back( string("stein of mead") );
       }
    }
    what have you and then actually use the list throughout your game. Of course, you may find out later it's easier to refactor this list into it's own class. Except now that you have done some preliminary work with the list, you can refactor it into a user-defined type that does exactly what you need and you have made zero design presumptions too early.

    However because it's just a global vector I wouldnt give it it's own header. Keep everything in the source file for now, you can make header files later for this if you refactor it.

    I think that's what Dave wants to say, but even if he didn't, I wanted to make sure that I wrote this down.
    Last edited by whiteflags; 07-19-2006 at 01:16 PM.

  14. #14
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    Whether you put each map in its own class, or all of the maps into one class depends on how interrelated they are. If you wouldn't need more than one instance of the class, that's fine. Not all classes need to be used more than once to be effective. The benefit of putting the global data into a class (or classes) is that all the effort of creating, initializing, and maintaining the data is encapsulated into a single object.

    In the simple case, if your vector from post #6 was a non-static member of a class called MyVectorManager, and the constructor of that class initialized the vector data, like you tried to do globally, then you could just create a global instance of MyVectorManager and its constructor will automatically do that work for you. If you have lots of these maps and vectors to initialize, you can still follow the same technique.

  15. #15
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    Ok gentleman. I believe I understood what's involved now.

    Thanks
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Strings Program
    By limergal in forum C++ Programming
    Replies: 4
    Last Post: 12-02-2006, 03:24 PM
  2. Programming using strings
    By jlu0418 in forum C++ Programming
    Replies: 5
    Last Post: 11-26-2006, 08:07 PM
  3. Reading strings input by the user...
    By Cmuppet in forum C Programming
    Replies: 13
    Last Post: 07-21-2004, 06:37 AM
  4. damn strings
    By jmzl666 in forum C Programming
    Replies: 10
    Last Post: 06-24-2002, 02:09 AM
  5. menus and strings
    By garycastillo in forum C Programming
    Replies: 3
    Last Post: 04-29-2002, 11:23 AM