C++ 检索容器';给定迭代器的s比较函数

C++ 检索容器';给定迭代器的s比较函数,c++,generics,c++11,C++,Generics,C++11,给定迭代器,是否可以检索/使用该迭代器引用的集合的正确比较函数 例如,假设我正在编写一个通用算法: template <class InIt, class T> void do_something(InIt b, InIt e, T v) { // ... } 模板 void do_某物(InIt b,InIt e,T v){ // ... } 现在,假设我想做一些简单的事情,比如在[b..e]中查找v。如果b和e是std::vector的迭代器,我可以简单地使用If(

给定迭代器,是否可以检索/使用该迭代器引用的集合的正确比较函数

例如,假设我正在编写一个通用算法:

template <class InIt, class T>
void do_something(InIt b, InIt e, T v) { 
    // ...
}
模板
void do_某物(InIt b,InIt e,T v){
// ...
}
现在,假设我想做一些简单的事情,比如在
[b..e]
中查找
v
。如果
b
e
std::vector
的迭代器,我可以简单地使用
If(*b==v)但是,让我们假设
b
e
std::map
上的迭代器。在这种情况下,我应该只比较键,而不是映射中包含的全部值类型

因此,问题是,给定映射中的迭代器,如何检索只比较键的映射的比较函数?同时,我也不想盲目地假设我正在使用
map
。例如,如果迭代器指向
,我希望使用定义为如果它们指向
向量
deque
,我可能必须使用
=
,因为这些容器没有定义比较函数


哦,差点忘了:我意识到在很多情况下,容器只有一个等价的
操作符迭代器不必连接到容器,因此它们不会提供关于它们不必连接到的容器的任何细节。这是基本的迭代器抽象:迭代器定义序列,而不需要regard到序列的来源。如果您需要了解容器,则必须编写接受容器的算法。

没有标准方法将迭代器映射到基础容器类型(如果有这样的容器)。您可能可以使用一些启发式方法来尝试确定哪个容器,尽管这并不简单,也可能无法保证

例如,您可以使用一个元函数来确定*value_type*是否为
std::pair
,这意味着这可能是一个
std::map
,并且在提取类型
K
T
之后,尝试使用一个元函数来确定迭代器的类型和
std::map::迭代器的类型e> 或
std::map::const_迭代器
匹配
X
Y
的特定组合


在地图的情况下,可能足以确定(即猜测成功的可能性很高)迭代器引用了一个
std::map
,但您应该注意,即使您可以使用它,甚至可以提取比较器的类型
X
,但这不足以在一般情况下复制比较器。虽然不常见(且不推荐)比较器可以有状态,如果不直接访问容器,您将无法知道比较器的特定状态。还要注意的是,在某些情况下,这种类型的启发式方法甚至没有帮助,在
std::vector
的某些实现中,迭代器类型直接是指针,在这种情况下,您不能区分数组中的“迭代器”和相同底层类型的
std::vector中的迭代器。

不幸的是,迭代器并不总是知道包含它们的容器(有时它们根本不在标准容器中)。即使是
迭代器
也只包含有关值类型的信息,而该值类型并没有明确告诉您如何进行比较

相反,让我们从标准库中汲取灵感。所有关联容器(
map
等)都有自己的
find
方法,而不是使用
std::find
。如果您确实需要在这样的容器上使用
std::find
,则不需要使用
find\u if


听起来你的解决方案是,对于关联容器,你需要一个
do\u some\u if
,它接受一个谓词,告诉它如何比较条目。

现在没有时间写一个答案,但这可能会有帮助。嗯,虽然没有太多。棘手的部分是获取容器。我对你的
集合
案例感到困惑
集合的mperator
需要是一个总的顺序,这与
操作符==
的情况不同。无论您是只比较映射项的键还是比较整个项,都是一样的吗?当然,不要紧——您可能对映射部分没有相等操作。“正确”比较函数可能不存在。您可能只需要创建一个traits类并使用它。例如:一些
string
vector
将迭代器实现为裸指针(利用顺序和连续的底层缓冲区)。即使你将容器作为参数,你仍然需要依靠技巧来区分
序列
关联容器
。我想写一个可靠工作的
是关联容器
是很困难的。@pmr:如果你只想支持标准容器,这个特性其实很简单……你只需要确定类型是否为
std::map
std::multimap
std::set
std::multiset
(以及无序版本,如果需要支持这些版本,尽管比较器的概念还不太清楚)