如何在 C++ 中定义自引用映射?
How to define a self-referential map in C++ ?
我可以这样定义结构:
struct A{
map<string,A> m;
};
我可以这样使用它:
A a;
a.m["abc"].m["def"];
但我想这样使用它:
a["abc"]["def"];
这需要 a
为 map<string,typeof(a)>
但我无法定义诸如 map<string,map<string,...>>
之类的内容
这不需要无限 space,但我不知道如何在 C++ 中定义这样的东西。我该怎么做?
你不能。对于 C++ 中的自引用数据结构,您需要使用指针。
即使如此
struct A {
map<string, A> m;
};
不正确,因为您使用类型 A
作为尚未完全定义的 std::map
的参数(此时它有一个 "incomplete type")。
它在大多数编译器中 "works",但不是正式有效的 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;
}
我可以这样定义结构:
struct A{
map<string,A> m;
};
我可以这样使用它:
A a;
a.m["abc"].m["def"];
但我想这样使用它:
a["abc"]["def"];
这需要 a
为 map<string,typeof(a)>
但我无法定义诸如 map<string,map<string,...>>
这不需要无限 space,但我不知道如何在 C++ 中定义这样的东西。我该怎么做?
你不能。对于 C++ 中的自引用数据结构,您需要使用指针。
即使如此
struct A {
map<string, A> m;
};
不正确,因为您使用类型 A
作为尚未完全定义的 std::map
的参数(此时它有一个 "incomplete type")。
它在大多数编译器中 "works",但不是正式有效的 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;
}