简体   繁体   中英

How to define a self-referential map in C++ ?

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;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM