繁体   English   中英

我可以使用地图的迭代器类型作为其映射类型吗?

[英]Can I use a map's iterator type as its mapped type?

我有一棵树,其节点是大字符串。 除了沿着从节点返回到根的路径之外,我真的不需要在树中导航,因此每个节点都包含字符串和指向其父节点的指针就足够了。 我还需要能够在树中快速找到字符串。 树的节点本身没有排序,因此这需要某种索引。 但是,这些字符串足够大,我不想通过将它们同时存储在我的树和索引中来复制它们。

如果 map 的键是字符串并且映射值是指向其父项的指针,我可以使用单个 std::map 实现我的树和索引。 但是,我想不出一种方法来编写这些类型中的任何一种。 我最好的猜测是这样的:

using Tree = std::map<std::string, typename Tree::const_iterator>;

或者可能:

using Node = std::pair<std::string const, typename Node const*>;
using Tree = std::map<std::string, Node const*>;

但是这些递归类型定义无法编译。 有没有办法在 C++ 中创建这种类型? 或者更好的方法来做我想做的事情?

您可以将迭代器包装在您自己的类型中并引用该类型来避免递归类型问题。

struct const_iterator_wrapper {
    using iterator_type = map<string, const_iterator_wrapper>::const_iterator;

    iterator_type iter;

    const_iterator_wrapper() {}
    const_iterator_wrapper(iterator_type _iter) : iter(_iter) {}
};

using tree = map<string, const_iterator_wrapper>;

using Node定义无法编译,但实际结构会:

struct Node {
    std::string const s;
    Node const* n;
};

没有提到节点的父节点在创建后是否会发生变化。 如果不是,那么set可能比map更合适。 (如果它确实改变了,那么set选项并没有完全脱离表格,但它可能需要削弱const正确性保证,可能是通过使父指针mutable 。)事实上,你可能不必改变你的数据结构就可以使用set

假设您的节点当前如下所示。

struct Node {
    std::string data;
    const Node * parent; // Might need to add `const`
};

您希望这些按数据排序,忽略父指针。 这可能需要定义一个新的 function。如果下面的operator<已经被定义为其他东西,那么定义你的set需要更多的工作,但仍然不难。

bool operator<(const Node &a, const Node &b) {
    return a.data < b.data;
}

这就是定义一组这些节点所需的全部内容,这些节点将 function 与您想要的 map 非常相似。

std::set<Node> tree;

// Add a root element.
auto result = tree.emplace("root", nullptr);
auto root_it = result.first;

// Add a child to the root.
tree.emplace("child", &*root_it);
// The `&*` combination may look odd. It is, though, a way to
// convert an iterator to a pointer.

有些人可能会发现一些意想不到的陷阱,但除了使用map作为此角色之外,别无其他。

最后,就数据的结构而言, map<K, const V>等价于set<pair<K, V>>比较合适 function。虽然成员函数不同,但最大的map 和一组对之间的真正功能差异在于地图的值可以更改(因此const V而不是之前的V )。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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