如何比较两个双向迭代器的(顺序)?
How to compare (the order) of two bidirectional iterators?
我想知道 C++ 中是否有内置方法来比较两个双向迭代器的顺序。例如,我有一个 Sum 函数来计算同一列表中 2 个迭代器之间的总和:
double Sum(std::list::const_iterator Start, std::list::const_iterator End){
double sum=0;
for (Start;Start!=End;Start++)
sum+=*Start;
return sum;
}
然后:
Sum(my_list.begin(),my_list.end());
可以,但是 Sum(my_list.end(),my_list.begin());
会导致运行时错误。
我想输入if (Start>End) return 0;
来防止错误。但似乎我不能像这样比较迭代器。
您应该阅读 Introduction to the STL,其中解释了迭代器概念的各种改进。
只有 RandomAccessIterators 支持与 <
的比较,因为它对于非 RandomAccessIterators 不是一个有效的操作。
判断 BidirectionalIterator i
是否小于另一个 j
的唯一方法是一次增加 i
一步,看看是否你曾经到达 j
,但如果 j
无法从 i
到达,那将永远不会发生,如果 i
不可递增,则这是一个错误,例如因为它是范围的尾后迭代器。
或者,您可以递减 i
并查看是否达到 j
,在这种情况下您知道 j
小于 i
,但那不会如果 i
是开始迭代器,则不起作用,因为您不能在范围开始之前进行迭代。
所以一般来说没有办法知道一个非RandomAccessIterator是在另一个非RandomAccessIterator之前还是之后,因为你甚至不知道是开始向前迭代还是向后迭代到达另一个,你也不知道当可以安全继续前进或到达有效范围的尽头时。
所以按照惯例,你总是以相同的顺序传递迭代器,这样开始迭代器首先出现,结束迭代器排在第二位,结束迭代器可以通过递增到达开始迭代器零次或多次。
Then: Sum(my_list.begin(),my_list.end());
is fine, but Sum(my_list.end(),my_list.begin());
will cause runtime error.
那就不要那样做!
正确调用函数是调用者的责任,为什么调用者不知道哪个迭代器是开始哪个是结束?
当您调用 Sum(my_list.begin(),my_list.end()) 时,my_list.begin() 将指向第一个元素列表
double Sum(std::list::const_iterator& Start, std::list::const_iterator& End)
{
double sum=0;
if (Start;Start!=End;Start++)
sum+=*Start;
return sum;
}
SameWay 当您调用 Sum(my_list.end(),my_list.begin()),my_list.end() 时将指向最后一个列表中的元素。
进行以下更改即可,
double Sum(std::list<int>::const_iterator Start, std::list<int>::const_iterator End)
{
double sum=0;
for (Start;Start!=End;Start)
sum+=*(--Start);
return sum;
}
我想知道 C++ 中是否有内置方法来比较两个双向迭代器的顺序。例如,我有一个 Sum 函数来计算同一列表中 2 个迭代器之间的总和:
double Sum(std::list::const_iterator Start, std::list::const_iterator End){
double sum=0;
for (Start;Start!=End;Start++)
sum+=*Start;
return sum;
}
然后:
Sum(my_list.begin(),my_list.end());
可以,但是 Sum(my_list.end(),my_list.begin());
会导致运行时错误。
我想输入if (Start>End) return 0;
来防止错误。但似乎我不能像这样比较迭代器。
您应该阅读 Introduction to the STL,其中解释了迭代器概念的各种改进。
只有 RandomAccessIterators 支持与 <
的比较,因为它对于非 RandomAccessIterators 不是一个有效的操作。
判断 BidirectionalIterator i
是否小于另一个 j
的唯一方法是一次增加 i
一步,看看是否你曾经到达 j
,但如果 j
无法从 i
到达,那将永远不会发生,如果 i
不可递增,则这是一个错误,例如因为它是范围的尾后迭代器。
或者,您可以递减 i
并查看是否达到 j
,在这种情况下您知道 j
小于 i
,但那不会如果 i
是开始迭代器,则不起作用,因为您不能在范围开始之前进行迭代。
所以一般来说没有办法知道一个非RandomAccessIterator是在另一个非RandomAccessIterator之前还是之后,因为你甚至不知道是开始向前迭代还是向后迭代到达另一个,你也不知道当可以安全继续前进或到达有效范围的尽头时。
所以按照惯例,你总是以相同的顺序传递迭代器,这样开始迭代器首先出现,结束迭代器排在第二位,结束迭代器可以通过递增到达开始迭代器零次或多次。
Then:
Sum(my_list.begin(),my_list.end());
is fine, butSum(my_list.end(),my_list.begin());
will cause runtime error.
那就不要那样做!
正确调用函数是调用者的责任,为什么调用者不知道哪个迭代器是开始哪个是结束?
当您调用 Sum(my_list.begin(),my_list.end()) 时,my_list.begin() 将指向第一个元素列表
double Sum(std::list::const_iterator& Start, std::list::const_iterator& End)
{
double sum=0;
if (Start;Start!=End;Start++)
sum+=*Start;
return sum;
}
SameWay 当您调用 Sum(my_list.end(),my_list.begin()),my_list.end() 时将指向最后一个列表中的元素。
进行以下更改即可,
double Sum(std::list<int>::const_iterator Start, std::list<int>::const_iterator End)
{
double sum=0;
for (Start;Start!=End;Start)
sum+=*(--Start);
return sum;
}