Search code examples
c++stringc-preprocessoridentifier

(How) can I use an array of strings as identifiers in C++?


I'm working on this project where I need to parse a text file that contains a two-column table consisting of names on the left and values on the right.

Now, I need to write those to specific places in a control table, which are identified using hexadecimal addresses; in a header file that I can't edit, they have been defined as such:

#define HARRY_POTTER 0x3A

There's then a writing function that takes an address and a value and writes it into a storage place (this function is also out of my control). So, calling this

write(0x3A, 7);

Would have the same result as calling this

write(HARRY_POTTER, 7);

Because of that definition in the header file.

Now, I've got the parsing down, which basically gives me the left column, the name, as a string (so, "HARRY_POTTER", for example), and the right column, the value, as an integer.

What I'm wondering is if there's any way to use this string, "HARRY_POTTER" as the identifier in the write function; essentially converting the string into an identifier, so that I could just loop through my entire array of parsed values and it would automatically write them to the address that matches the string/ the name in the left column.

Is this possible? If yes, how?


Solution

  • No, it's not possible as you ask. The reason is because the string that you read from the file is only known at run-time, while preprocessing occurs at compile-time, so HARRY_POTTER must already have been replaced. In fact, no identifiers at all exist after the program has been compiled.

    What you may want it to introduce a mapping from std::strings to the constants that you have defined. For example:

    std::unordered_map<std::string, int> mapping = {{"HARRY_POTTER", HARRY_POTTER},
                                                    {"RON_WEASLEY", RON_WEASLEY}};
    

    The constants will be replaced at compile-time, of course, so this is just equivalent to:

    std::unordered_map<std::string, int> mapping = {{"HARRY_POTTER", 0x3A},
                                                    {"RON_WEASLEY", 0x7C}};
    

    Then you can call write with:

    write(mapping.at(key), 7);
    

    Where key is a string with a value like "HARRY_POTTER".