【问题标题】:How to invoke a `find` on a set of iterators, looking up by what the iterator points to?如何在一组迭代器上调用“find”,通过迭代器指向的内容进行查找?
【发布时间】:2020-06-16 00:02:09
【问题描述】:

在 c++17 中,我尝试了以下方法来获得有序的对列表,以及一种能够根据对中的第一个元素快速找到该列表中的随机条目的方法。这个想法是创建一个类,其中通过对的普通迭代将以固定顺序进行,同时仍然可以有效地随机访问它们。 unordered_list 中的条目旨在仅作为 ordered_list 的迭代器,忽略线程安全隐患,ordered_list 和 unordered_list 将始终一起更新。这是一个类似于我尝试的代码片段:

class ordered_pairs {
public:
    typedef std::list<std::string, std::string> list_t;

    struct iterator_hash {
        std::size_t operator()(const list_t::iterator &it) const; // hash of first element in pair
        std::size_t operator()(const std::string &s) const;
    };
    struct iterator_eq {
        bool operator()(const list_t::iterator &left, const list_t::iterator &right) const; // compares first elements of each pair
        bool operator()(const list_t::iterator &left, const std::string &right) const; // compares first element to a string
    };

    list_it::iterator find(const std::string &s)
    {
        auto iter = unordered_list.find(s);
        if (iter == unordered_list.end()) {
            return ordered_list.end();
        } else {
            return *iter;
        }
    }
    ...
private:
    std::unordered_set<list_t::iterator, iterator_hash, iterator_eq> unordered_list;
    list_t ordered_list;
};

然而,我发现的问题在于我的find() 方法,编译器抱怨无法将std::string 转换为存储在ordered_list 中的迭代器类型。我曾想过如果我在iterator_hashiterator_eq 中重载operator() 以获取字符串参数和迭代器,我将能够快速搜索集合中的条目。然而,事实并非如此。

到目前为止,我发现的唯一解决方法是将 find 更改如下:

list_it::iterator find(const std::string &s)
{
    list_t dummy;
    dummy.insert(std::pair(s,""));
    auto iter = unordered_list.find(dumy.begin());
    if (iter == unordered_list.end()) {
        return ordered_list.end();
    } else {
        return *iter;
    }
}

但是,此方法涉及创建一个新列表,向其中添加一个元素只是为了获取它的迭代器,并且将元素添加到该列表将调用动态堆分配(并在退出函数时释放)。有什么方法可以在我的 unordered_list 中搜索迭代器,我可以通过初始字符串进行搜索?

如果我的问题不清楚,请随时在下面的 cmets 中提问,我将努力澄清我对我的问题进行修改的问题。

【问题讨论】:

    标签: c++ list search c++17 unordered-set


    【解决方案1】:

    无序容器的异构查找是 C++20 的一项功能(P0919P1690)。根据cppreference 的说法,MSVC 19.23 是迄今为止唯一支持此功能的主要标准库之一。

    直到 C++20,unordered_set::find 仅有的两个重载是:

    iterator find( const Key& key );
    const_iterator find( const Key& key ) const;
    

    这就是您收到您所看到的错误的原因。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-07-20
      • 1970-01-01
      • 2023-04-10
      • 2010-10-09
      • 1970-01-01
      • 2012-06-18
      • 2016-04-09
      • 2017-08-29
      相关资源
      最近更新 更多