0

In my code I'm using multiple structs of the following structure:

struct Track {
    string artist;                      
    string cd;                          
    // etc....  
};

The structs can be referred to as: Track1, Track2, etc.
I'm trying to make a function that uses a variable to determine which member it should output.
For example:

string x ="cd"                                
cout << Track1.x << endl;

I can't really figure out how to do this... I keep getting the error that 'x' is not a member of the Struct.

Thanks for taking time to read this, I hope you can help me out.

1
  • What is your outer problem? Why do you need a function like this? How is it going to be called? What's wrong with code like if (x == "cd") return o.cd;? Commented Jan 7, 2016 at 19:50

2 Answers 2

7

C++ is not a scripting language, so you can't do "variable variables" like that.

The usual way to do this is to use a map instead:

std::map<std::string, std::string> myValues;

Then the following are the same:

std::cout << myValues["cd"] << std::endl;

and

std::string x = "cd";
std::cout << myValues[x] << std::endl;

However, I question your design. It seems like a track has a fixed number of properties so individual members make sense, rather than a map to which elements may be added and removed. You could restrict access to the map and write code that ensures it has all the track properties stored within it (and nothing else) at all times.

But I suggest revisiting the need for "variable variables" here in the first place. Passing a string into a function to determine its semantics doesn't seem particularly efficient, robust or resilient. Why not return a reference to the entire Track object, then the caller can examine any property they want?

std::cout << getTrack(arguments...).cd << std::endl;
Sign up to request clarification or add additional context in comments.

1 Comment

thanks for the fast response! I'm new to c++ so I really appreciate your explanations. I'm sorry if it wasn't clear why I would use this method. I removed some unessecary concepts to make the problem more readable. I will take some time to understand/implement your awnsers and to explain the problem a bit better (i have some difficulties doing this in english).
0

It is not possible to specify a class member by a run-time name. The only immediate language feature that allows one to specify a class member by a run-time value (i.e. as you put it "use a variable to determine struct member") is pointers of "pointer-to-member" type

Track track1 = { "Some Artist", "Some CD" };
Track track2 = { "Some Other Artist", "Some Other CD" };

std::string Track::*member = &Track::cd; // pointer-to-member points to 'cd' member
std::cout << track1.*member << std::endl;
std::cout << track2.*member << std::endl;

member = &Track::artist; // pointer-to-member points to 'artist' member
std::cout << track1.*member << std::endl;
std::cout << track2.*member << std::endl;

Now, if you want to be able to select a specific member using a string containing its name (as in your original post), you have no other choice but to implement the name-to-member mapping manually. You can use the aforementioned pointer-to-members to build such mapping

std::map<std::string, std::string Track::*> mapping = {
  { "artist", &Track::artist },
  { "cd", &Track::cd }
};

std::string Track::*member = mapping["cd"];
std::cout << track1.*member << std::endl;
std::cout << track2.*member << std::endl;

1 Comment

thanks for the fast response! I'm new to c++ so I really appreciate your explanations. I'm sorry if it wasn't clear why I would use this method. I removed some unessecary concepts to make the problem more readable. I will take some time to understand/implement your awnsers and to explain the problem a bit better (i have some difficulties doing this in english).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.