我想知道我们是否可以为非随机operator <
重载iterators
,例如std::list
,std::map
等。例如,如果我重载它对于std::list
然后:
bool operator < (std::list<T>::iterator &i1, std::list<T>::iterator &i2)
{
return (&*i1 < &*i2);
}
我的主要目的是进行这样的迭代:
for (auto i = l.begin(); i < l.end(); ++i) // possible for std::vector, std::deque, etc
// I want to do this instead of i != l.end()
但是编译器说:
[错误]声明
operator<
为非功能
任何人都有解决方案吗?
答案 0 :(得分:3)
你的工作方向错误。由于某种原因,非随机访问迭代器不支持operation <
。基本上,不可能以合理的方式为非随机访问迭代器实现operation <
。在你的情况下,你应该写:
for (auto i = l.begin(); i != l.end(); ++i)
代替。或者,如果支持C ++ 11,请考虑使用基于范围的for循环的可能性。
关于你的代码:
bool operator < (std::list<T>::iterator &i1, std::list<T>::iterator &i2)
{
return (&*i1 < &*i2);
}
两种方式都不行。
std::list<T>::iterator
是一个从属名称。您需要使用typename
。T
的模板参数。必须明确指定。那么,如何解决第二个问题呢?好吧,我认为不可能。迭代器的实际类型未在标准中指定,并被视为实现细节。
答案 1 :(得分:3)
对不提供它的迭代器进行小于比较是没有意义的。使用带有std::list
的示例,列表中的节点可以位于内存中的任何位置。尝试比较节点的地址是没有意义的,因为第一个节点可能具有比所有其他节点更高的地址。如果是这种情况,那么你永远不会遍历列表。这种方法的唯一方法是使用一个标记节点(end
)并进行每次迭代检查以确定是否与它不相等。通过这样做,你知道你没有达到目的,你可以继续。一旦你比较等于end
,你知道你已经到达列表的末尾。
答案 2 :(得分:1)
我建议使用std::remove_if
(然后当然是erase
),这更清楚你正在做什么,也应该是有效的。如果你可以使用C ++ 11那么谓词可以是一个lambda,而且它非常紧凑。