如何在C ++中定义自引用映射?

时间:2015-10-31 07:25:17

标签: c++ dictionary struct self-reference

我可以像这样定义一个结构:

struct A{
    map<string,A> m;
};

我可以这样使用它:

A a;
a.m["abc"].m["def"];

但我想这样使用它:

a["abc"]["def"];

这需要amap<string,typeof(a)>

但我无法定义诸如map<string,map<string,...>>

之类的内容

这不需要无限空间,但我不知道如何在C ++中定义这样的东西。我怎么能这样做?

1 个答案:

答案 0 :(得分:2)

你做不到。对于C ++中的自引用数据结构,您需要使用指针。

即便如此

struct A {
    map<string, A> m;
};

不正确,因为您使用类型A作为尚未完全定义的std::map的参数(此时它具有“不完整类型”)。

它在大多数编译器中“有效”,但不是正式有效的C ++代码。

但是请注意,如果您的实施已经接受了operator[]成员,那么如果您只需要链接map<string, A>,这很容易做到:

struct A {
    map<string, A> m;
    A& operator[](const string& key) {
        return m[key];
    }
}

编译g ++和clang ++的例子(但请记住它不是有效的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;
}