I can define a struct like this:
struct A{
map<string,A> m;
};
and I can use it like this:
A a;
a.m["abc"].m["def"];
but I want to use it like this:
a["abc"]["def"];
this requires a
to be map<string,typeof(a)>
but i can't define something such as map<string,map<string,...>>
this does not need infinite space, but i don't know how to define such a thing in C++. How can I do that?
You cannot. For self-referential data structures in C++ you need to use pointers.
Even the case
struct A {
map<string, A> m;
};
is not correct because you're using type A
as a parameter to std::map
that has not been fully defined yet (it has an "incomplete type" at that point).
It "works" in most compilers, but is not formally valid C++ code.
Note however that if all you need is chained operator[]
this is easy to do if your implementation is already accepting the map<string, A>
member:
struct A {
map<string, A> m;
A& operator[](const string& key) {
return m[key];
}
}
An example that compiles on g++ and clang++ (but remember that it's NOT valid C++):
#include <map>
#include <string>
#include <stdio.h>
struct A {
std::map<std::string, A> m;
A& operator[](const std::string& x) { return m[x]; }
};
void dump(const A& a, int indent=0) {
for (auto& i : a.m) {
printf("%*s%s\n", indent, "", i.first.c_str());
dump(i.second, indent+2);
}
}
int main(int argc, const char *argv[]) {
A a;
a["1"]["1.1"];
a["1"]["1.2"];
a["1"]["1.3"];
a["2"]["2.1"];
a["2"]["2.2"];
a["3"]["3.1"]["3.1.1"]["3.1.1.1"];
a["4"];
dump(a);
return 0;
}