Convert member variable name to a string
Asked Answered
M

3

1

Can I enumerate char* members of a class (or struct) in C++? If so can I print the variables names as strings? Using pre-processor?

I have a class with all const char* members. It would be good if there was an elegant way to enumerate each member variable and check name as a string against a string key I am given.

Here is the sort of code which could be used?

Can anyone think of a way to do this?

class configitems {
public:
   configitems() : host(0), colour(0) {}
   const char* host;
   const char* colour;
   //... etc
};

int main() {

   configitems cfg;
   //cfg.colour = "red";

   //receive an config item as a string.  I want to check that the item is a valid one (eg is a 
   //variable of class configitem) and then populate it.

   //eg get colour=red so want to do something like this:
   if(isConfigItem("colour")) {
      cfg.<colour> = "red";
   }
   return 0;
}
Missie answered 21/3, 2013 at 14:28 Comment(1)
No, and it seems you're approaching the problem the wrong way anyway.Apophysis
E
1

As others have said, the name of a variable doesn't actually exist in the generated code once the compiler has finished compiling the code. It may exist in debug symbols or some such, but that's a horrible mess to try to reach into to determine where your variable is located [it may well reside in different places depending on whether the compiler currently is using a register or memory location to store its value, etc, etc].

It is certainly possible to have a macro that produces the matching strin to a name in a parameter.

However, it's probably better to use a different mechanism for configuration type things - a couple of obvious options are:

  1. Using a std::map<std::string, std::string>
  2. Using an array or a vector of std::pair<std::string, std::string>

You could also have a piece of fixed code that understands different configuration settings and their translation to variables. It's not at all a bad solution as long as there aren't a huge number of them.

Or you could build an array like this:

enum config_vals
{
    host,
    color,
    ...
    max_config
};

struct translation
{
   const char *name;
   config_vals val;
};

#define TRANS(x) { #x, x }

translation trans[]] = {
    TRANS(host),
    TRANS(color),
};

class configitems
{
  ...
  std::string value[max_configs];
  ...
}

... 

configitems c;
...
if (c.value[host] == "localhost") ... 
Endearment answered 21/3, 2013 at 14:43 Comment(0)
I
1

In C++, it is impossible to convert the name of a variable to a string. In some cases, the variable name does not even exist in the compiled executable (depends on scoping and visibility).

Even if it was possible, it is still impossible to enumerate the members of a class.

Another way to go about this problem would be to use an std::map instead that uses strings like "host" as keys, and enumerate this.

Indentation answered 21/3, 2013 at 14:32 Comment(2)
Using a (not-so-pretty) macro, you can convert a variable name to its string representationProtero
@IvayloStrandjev: True, but at that point the particular variable is already hardcoded, and you might as well hardcode the name. Anyway, the OP wants enumeration, which is not possible even with your macro.Indentation
E
1

As others have said, the name of a variable doesn't actually exist in the generated code once the compiler has finished compiling the code. It may exist in debug symbols or some such, but that's a horrible mess to try to reach into to determine where your variable is located [it may well reside in different places depending on whether the compiler currently is using a register or memory location to store its value, etc, etc].

It is certainly possible to have a macro that produces the matching strin to a name in a parameter.

However, it's probably better to use a different mechanism for configuration type things - a couple of obvious options are:

  1. Using a std::map<std::string, std::string>
  2. Using an array or a vector of std::pair<std::string, std::string>

You could also have a piece of fixed code that understands different configuration settings and their translation to variables. It's not at all a bad solution as long as there aren't a huge number of them.

Or you could build an array like this:

enum config_vals
{
    host,
    color,
    ...
    max_config
};

struct translation
{
   const char *name;
   config_vals val;
};

#define TRANS(x) { #x, x }

translation trans[]] = {
    TRANS(host),
    TRANS(color),
};

class configitems
{
  ...
  std::string value[max_configs];
  ...
}

... 

configitems c;
...
if (c.value[host] == "localhost") ... 
Endearment answered 21/3, 2013 at 14:43 Comment(0)
D
0

There's no way in C++ to do exactly what you're trying to do. But if all you want is a collection of key-value pairs, there are solutions.

For example, instead of class configitems, make it a std::map<std::string, std::string> configitems:

std::map<std::string, std::string> configitems;
//...
configitems.insert( std::pair<std::string,std::string>( "colour", "red" ) );
Diaz answered 21/3, 2013 at 14:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.