在给定迭代器的情况下检索容器的比较函数
Retrieve container's comparison function given an iterator
给定一个迭代器,是否可以为该迭代器引用的集合检索/使用正确的比较函数?
例如,假设我正在编写一个通用算法:
template <class InIt, class T>
void do_something(InIt b, InIt e, T v) {
// ...
}
现在,假设我想做一些简单的事情,比如在[b..e)
中查找v
。如果b
和e
是std::vector
上的迭代器,我可以简单地使用if (*b == v) ...
。然而,让我们假设b
和e
是std::map
上的迭代器。在这种情况下,I应该只比较键,而不是映射中包含的整个值类型。
所以问题是,如果映射中有这些迭代器,我如何检索映射的比较函数,该函数只比较键?同时,我也不想盲目地认为我在使用map
。例如,如果迭代器指向一个set
,我希望使用为该set
定义的比较函数。如果它们指向vector
或deque
,我可能不得不使用==
,因为这些容器没有定义比较函数。
哦,差点忘了:我意识到,在很多情况下,容器中包含的元素只有operator<
而不是operator==
的等价物——我完全可以使用它。
迭代器不必连接到容器,因此它们不会向您提供关于它们不一定连接到的容器的任何详细信息。这是基本的迭代器抽象:迭代器对序列进行定界,而不考虑序列的来源。如果你需要了解容器,你必须编写使用容器的算法。
没有标准的方法可以从迭代器映射到底层容器类型(如果有这样的容器的话)。您可能可以使用一些启发式方法来尝试确定哪个容器,尽管这并不简单,也可能无法保证。
例如,您可以使用元函数来确定*value_type*是否为std::pair<const K, T>
,这暗示这可能是std::map
,并且在提取类型K
和T
之后,尝试使用元函数确定迭代器的类型以及std::map<K,T,X,Y>::iterator
或std::map<K,T,X,Y>::const_iterator
的类型是否匹配X
、Y
的特定组合。
在映射足以确定(即猜测成功几率很高)迭代器引用std::map
的情况下,但您应该注意,即使您可以使用它,甚至提取比较器的类型X
,在一般情况下,这也不足以<em]复制>比较器。虽然不常见(不推荐)的比较器可以有状态,如果不直接访问容器,您将不知道比较器的特定状态。还要注意,在某些情况下,这种类型的启发式甚至没有帮助,在std::vector<>
的某些实现中,迭代器类型直接是指针,在这种情况下,您无法区分将"迭代器"划分为数组,将迭代器划分为相同底层类型的std::vector<>
。
不幸的是,迭代器并不总是知道包含它们的容器(有时它们根本不在标准容器中)。即使是iterator_traits
也只有关于value_type的信息,并没有具体告诉您如何进行比较。
相反,让我们从标准库中汲取灵感。所有关联容器(map
等)都有自己的find
方法,而不是使用std::find
。如果确实需要在这样的容器上使用std::find
,则不需要:使用find_if
。
听起来你的解决方案是,对于关联容器,你需要一个do_something_if
,它接受一个谓词,告诉它如何比较条目。
- C++自定义比较函数
- 使用自定义比较函数使用std::sort()对矢量字符串进行排序时出现问题
- 隐式转换为比较函数对象(函子)用于 std::sort 而不是 std::map?
- 为什么 std::stable_sort() 的比较函数的参数必须是设置常量?
- 如何定义集合数组的比较函数?
- 根据比较函数C++对数组进行排序
- 使用自定义比较函数在类内进行列表排序
- 如何更改 std::set 的比较函数?
- 使用类似的比较函数时,在 c++ 中为 std:sort 获得不同的结果
- std::映射服装比较函数和函数/lambda错误
- 在C++排序中为比较函数指定参数
- 使用右值的比较函数
- 为什么比较函数类型需要指定为模板参数?
- 我应该将 lambda 或函子用于比较函数吗?
- 比较函数模板中的 VARTYPE 和 typeid().name / typename
- 如何键入定义一个专门的 std::set 模板,使用特定的比较函数实例化
- 无法在 std::sort 中使用 cdef 函数作为比较函数
- 关联容器,比较函数不是元素类型的一部分吗?
- 标准::lower_bound的比较函数
- 关于如何在 std::sort 和 std::p riority_queue 中使用自定义比较函数的困惑