views:

96

answers:

3

Hi, I have a little problem in C++ I don't know how to solve. The first part of the problem is to access an element in a struct via [], or better, to map [] to a subelement.

My struct looks like this:

struct e {
    std::string content;
    std::string name;
    std::map<std::string, std::vector<e> > elements;
};

If I want to access a subelement of e, I can do this like this: e.elements["e1"][0].elements["e1sub"][0].content, would it be possible to map this so I can call it like this: e["e1"][0]["e1sub"][0], this would just mean that he has to "replace" every e[] with e.elements[].

Maybe this can be done with templates but I don't know how to use them yet as I'm just beginning to learn C++.

Thanks in advance for any help, Robin.

+4  A: 

You need to overload operator[]. Typically, you want to implement two versions of that operator, but since std::map only overloads the non-const version, that might be enough for you.

Something like the following should do:

struct e {
    std::string content;
    std::string name;
    std::map<std::string, std::vector<e> > elements;

    std::vector<e>& operator[](const std::string& key) {return elements[key];}
};
sbi
This is a good answer, but if you're overloading operators, maybe it's time to put the data into a real class?
Falmarri
Thank your very much sbi :)
Robin
@Falmarri: You do have a very valid point there.
sbi
+2  A: 

You can "overload" the [] operator, try:

struct e {
    std::string content;
    std::string name;
    std::map<std::string, std::vector<e> > elements;
    std::vector<e>& operator [](const std::string& s);
};

...

std::vector<e>& e::operator [](const std::string& s) {
    return elements[s];
}
tauran
Yes right, I made changes accordingly :)
tauran
In C++ there is absolutely no need for `typedef struct e {...} e;` - that was only necessary in C.
Georg Fritzsche
Really? That's neat, didn't know that...
tauran
+1  A: 

You don't need templates. You merely need an operator[] :

std::vector<e>& e::operator[](std::string const& s) { return this->elements[s]; }
// elements.operator[s] inserts s if it doesn't exist yet. That's non-const so the following won't work
// std::vector<e> const& e::operator[](std::string const& s) const { return this->elements[s]; }
MSalters
The `const` version would have to be much more elaborate than that for `std::map`. Also, implementing it you'll face the same problem that lead to `std::map` not having a `const` overload of `operator[]()`. And you need to upgrade your spill chucker. `:)`
sbi
ofc, explained.
MSalters
@MSalters: 1) You didn't attribute your comment answer and I only came by here accidentally. 2) I don't know what "ofc" stands for.
sbi
@sbi: I didn't attribute the comment since it wasn't a response. I added a comment for other readers, so they would not be misled to believe that your comment applies to the latest code. "ofc" stands for "of course", which I believed to be a common abbreviation.
MSalters