假设我有一个我将调用NamedNestedMap
的类型std::map<std::string, std::map<std::string, NamedNestedMap> >
在这种情况下,该对的每秒(值)与父对象的类型或类型相同。我无法弄清楚的是如何宣布它。这将允许递归算法通过地图的“树”向下走。
Value类型与父类型相同,在我需要引用它的时候,它没有完全声明。
你如何宣布像这样嵌套的东西......
我甚至无法输入第一个,因此我可以将其包含在第二个中,因为它不完整
递归会在地图中查找某些内容,当它找到它时,会递归该对象的值。算法部分看起来很简单,声明部分就是这里的难点。我不是要迭代地图的地图,只需使用map.find,recurse并再次使用map.find。
答案 0 :(得分:8)
你必须使用指针(当然,否则递归永远不会终止 - 你总是需要一个空的地图):
struct NestedMap;
struct NestedMap : std::map<std::string, NestedMap*> {};
当然,您可能希望使用shared_ptr
或类似的东西来管理内存,而不是原始指针。
答案 1 :(得分:5)
创建表示节点的结构。
struct Node {
std::map<std::string, Node *> children;
};
当然,你可以将它变成一个类并隐藏数据等。
答案 2 :(得分:4)
我想你想要一个深度为n的嵌套地图:
template<class key_type, class val_type, int nest_depth>
struct nest
{
typedef std::map<key_type, typename nest<key_type, val_type,
nest_depth-1>::map_type> map_type;
};
template<class key_type, class val_type>
struct nest<key_type, val_type, 0>
{
typedef std::map<key_type, val_type> map_type;
};
像这样使用:
nest<std::string, std::string, 2> nested_map;
答案 3 :(得分:2)
您无法声明递归结构。
你可能做的最好的事情就是有一张指针地图。
答案 4 :(得分:1)
问题是NamedNestedMap
的类型定义在其递归结构中没有终止。 NamedNestedMap
的模板扩展将是无限的,因此无法在代码中表示它。
答案 5 :(得分:1)
听起来你想做这样的事情:
class Node {
...
std::map<std::string, Node*> children;
}
在这里,每个Node
在地图中都有一个“儿童”地图,这个孩子可以有孩子,等等。
答案 6 :(得分:0)
你不能以你呈现它的方式去做,而你可能不想这样做。 原因是地图中的对按值存储。 您是否希望将您的名称 - 值表复制到另一个容器中? 我会选择@strager和Pavel提出的包装纸, 可选择使用智能指针。
答案 7 :(得分:0)
这似乎为我编译:
#include <map>
#include <string>
struct RecMap
{
std::map<std::string, RecMap> m;
};
int main()
{
RecMap rec;
rec.m["first"] = RecMap();
rec.m["first"].m["second"] = RecMap();
}
不是100%确定它是否合法(例如,你有一个包含vector<X>
作为成员的X类吗?)。这里的递归并不是无限的,因为最终你会遇到一个包含空映射的RecMap。
编辑:this article讨论了这种情况。结论:未定义。遗憾。
答案 8 :(得分:0)
我认为创建递归结构会给你带来麻烦。只需使用法线贴图,如下所示:
#include <map>
#include <string>
using namespace std;
int main() {
map<string, map<string, string> > nest;
nest["first"]["second"] = "Hello nest!";
printf("%s\n", nest["first"]["second"].c_str());
return 0;
}
这是执行:
$ g++ ./nest.cpp -o nest.out -ansi -pedantic -std=c++98
$ ./nest.out
Hello nest!
$