【问题标题】:Why unordered_set<string::iterator> does not work?为什么 unordered_set<string::iterator> 不起作用?
【发布时间】:2020-09-22 19:00:27
【问题描述】:

我正在尝试获取要从字符串中删除的迭代器列表。我想用 unsorted_set 来做,因为访问时间是恒定的,我会经常查找,但它给了我一个编译错误。 unordered_set&lt;string::iterator&gt; to_erase 但是,如果我尝试定义 vector&lt;string::iterator&gt; to_erase 它会起作用。

但是当我尝试这样做时:

find(to_erase.begin(),to_erase.end(),it)

没用

【问题讨论】:

  • 您可能在这里遇到了 XY 问题——试图找到一个问题的解决方案和另一个问题的解决方案——如果你描述了过度的问题,有人可能会提出更好的解决方案过度的问题。
  • 您想要一个用于擦除的迭代器列表,但您想在该列表中进行大量查找?如果您正在擦除某些内容,那么您肯定不需要多次查找它。你到底想做什么?
  • 请记住,一旦您开始删除,迭代器通常很快就会失效。我还没有找到对std::string 失效规则的直接引用,但我怀疑它们与std::vector 会有很大不同。无论如何,当您开始通过可删除的迭代器的无序列表进行删除时,很有可能您在有机会删除它们之前至少使一些后来的迭代器无效

标签: c++ string c++11 vector


【解决方案1】:

我还没有检查,但看起来字符串迭代器没有定义哈希码。任何存储在 unordered_* 中的东西都必须有一个散列。

我不确定你会怎么做,因为迭代器的内部 char* 对你隐藏。


Mooing Duck 贡献了以下来自http://coliru.stacked-crooked.com/a/a8d75d3ac153a799

#include <iostream>
#include <vector>
#include <string>
#include <unordered_set>

struct str_it_hasher {
    std::size_t operator()(std::string::const_iterator it) const {
        return std::hash<const char*>{}(&*it);
    }
};


int main() {
    std::unordered_set<std::string::iterator, str_it_hasher> set;
    std::string a = "apple";
    set.insert(a.begin());
    set.find(a.begin());
    set.erase(a.begin());
}

【讨论】:

  • 你是对的。通过 g++ 快速运行它会产生一个神秘的错误,但你会得到这个重要的一点:no match for call to ‘(const std::hash&lt;__gnu_cxx::__normal_iterator&lt;char*, std::__cxx11::basic_string&lt;char&gt; &gt; &gt;)
  • 我相信您可以将自定义哈希函数传递给unordered_set,这将解决问题。
  • @MooingDuck 当然可以,但是你会用什么来从迭代器中读取?
  • coliru.stacked-crooked.com/a/a8d75d3ac153a799 它指向的字符的地址(你应该在你的答案中编辑这个或类似的东西)
  • @MooingDuck 哦,鬼鬼祟祟!
【解决方案2】:

字符串的迭代器可以很容易地来回转换为索引:

auto idx = iter - str.begin();
auto iter = idx + str.begin();

然后你可以存储索引。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-31
    • 2013-05-24
    • 2011-03-20
    • 2015-03-06
    • 2019-10-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多