我有一个Config
类,其中包含<string, string>
map
个数据,用于保存配置键和值。有时候,我不知道什么时候在编译时,我希望能够访问该对象中的一个键作为该对象的另一个(子)实例 - 我希望能够在理论上无限地嵌套
未解析的数据看起来像这样
someKey = someVal
keysnkrates = "itsastring"
# comments
keyConfig = (
subKey = 1
another = 3.14159
subKeyConfig = (
...inf...
)
)
otherVals = ...
如何在不诉诸类似C语言的方法的情况下解析类似的东西?我不想处理原始指针,我不想处理空值,但是我提出的唯一解决方案是使用指向Config
类的指针,如果它是{{ 1}}然后它是一个子配置对象。
答案 0 :(得分:3)
只使用普通的STL地图。你认为(至少)一些JSON和XML解析器如何在C ++中工作?
struct Config{
Data data;
std::map <std::string,Config> children;
}
现在你想要的内巢值:
Config config;
config.children["My Inner Config "] = Config(<my data>);
config.children["My Inner Config "].children["My inner inner config"] = Config(<more data>);
答案 1 :(得分:1)
有时问题的最佳解决方案是由具体问题的具体细节决定的。在您的情况下,其中一个细节是您最终如何使用结果数据结构(哪种形式的查询应该快速工作/工作?)。
除此之外,如果您发现问题的特定属性并以机会主义的方式利用它们,有时可能会出现“快捷方式”。
虽然输入数据的结构显然意味着树状数据结构,但是如果子配置数据中的密钥在所有级别上的所有发生密钥的集合内是唯一的,则一种可能的机会捷径。然后你可以简单地使用地图并依赖没有同义词密钥。当然,这会从您的数据中删除结构信息,您需要决定是否可以使用它。
扩展这个想法,有时你也可以通过重新思考你用作地图键的方法来避免实现树:现在你使用一个字符串。它也可以是类似(密钥,级别)的元组,或者是层次结构中的密钥到“路径”(例如“top / topchild / topchildchild”)的串联。同样,这取决于您稍后将如何处理数据,如果这对您来说是可行的方法。
最后,如果你找到一种方法将push_back()新条目放入数组并使用数组索引来表达父/子关系,你还可以实现没有经典树结构(指针)的树。
答案 2 :(得分:0)
如果你这样写:
struct foo {
int a, b, c;
struct bar nested_struct;
}
然后,每次分配新的foo
时,您都会为三个整体分配足够的空间,分配整个bar
对象,无论这个对象有多大。
你不能以这种方式“无限地”嵌套结构/类,因为你的计算机没有无限的内存。
我不知道 raw 指针是什么意思,但是如果你不想使用指针和NULL创建自己的链接数据结构,那么你可能应该使用一些预先定义的来自标准库的容器类。†
我不是C ++程序员,所以我不知道哪些类和库可用,但我确信它们都在那里。
†(编辑)不可能。您编写的每一行代码最终都成为一种责任。如果您正在编写真实的(商业)软件,那么编写更多的行总是错误的,而不是您绝对需要解决手头的问题。如果有一个库可以满足您的需求,那么您应该使用它。
答案 3 :(得分:0)
稍微复杂一点的做法(比接受的答案)是使用boost::variant
来表示可能的孩子以及每个节点可能的数据。
struct Node;
typedef boost::variant<int, std::string, boost::recursive_wrapper<Node>> Value;
struct Node {
std::map<std::string, Value> children;
};
或者沿着这些方向的东西。 这很好,因为如果你添加几种不同的类型作为有效值,你不需要在你的各种结构中有10个不同的子节点,这可以在你想要支持的方法中生成很多样板代码。 / p>