如何在一组迭代器上调用“查找”,通过迭代器指向的内容进行查找?
How to invoke a `find` on a set of iterators, looking up by what the iterator points to?
在 c++17 中,我尝试使用以下方法来获得一个有序的对列表,以及一种能够根据对中的第一个元素快速找到该列表中的随机条目的方法。这个想法是创建一个 class ,其中通过对的普通迭代将以固定顺序进行,同时仍然可以有效地随机访问它们。 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_hash
和 iterator_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
中搜索迭代器,我可以只按初始字符串搜索吗?
如果我的问题不清楚,请不要犹豫,在下面的评论中提问,我会努力澄清问题,我会修改我的问题。
无序容器的异构查找是 C++20 的一项功能(P0919 and P1690). According to cppreference,MSVC 19.23 是迄今为止唯一支持此功能的主要标准库。
C++20 之前,unordered_set::find
仅有的两个重载是:
iterator find( const Key& key );
const_iterator find( const Key& key ) const;
这就是您收到所见错误的原因。
在 c++17 中,我尝试使用以下方法来获得一个有序的对列表,以及一种能够根据对中的第一个元素快速找到该列表中的随机条目的方法。这个想法是创建一个 class ,其中通过对的普通迭代将以固定顺序进行,同时仍然可以有效地随机访问它们。 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_hash
和 iterator_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
中搜索迭代器,我可以只按初始字符串搜索吗?
如果我的问题不清楚,请不要犹豫,在下面的评论中提问,我会努力澄清问题,我会修改我的问题。
无序容器的异构查找是 C++20 的一项功能(P0919 and P1690). According to cppreference,MSVC 19.23 是迄今为止唯一支持此功能的主要标准库。
C++20 之前,unordered_set::find
仅有的两个重载是:
iterator find( const Key& key ); const_iterator find( const Key& key ) const;
这就是您收到所见错误的原因。