简体   繁体   中英

why can't i use list iterator logical comparisons operator?

It's very basic, but I could not find a similar question here. I am trying to iterate the same sorted STL list from different directions using list. I know I can compare an iterator to the list.begin() and list.end() , so why doesn't this work?

list<family>::iterator itLargeFamily = 
                  families.begin(); //starts from the biggest families
list<family>::iterator itSmallFamily = 
                  families.end(); //starts from the smallest families

for (; itSmallFamily > itLargeFamily; --itSmallFamily, ++itLargeFamily) {
    // stuff...
}

The error is of course

no operator > matches these operands

100% chance I'm missing something basic.

Only random access iterators are ordered. std::list iterators are only bidirectional iterators, so they do not support operator< or operator> .

Instead, you could do your comparison with != .

while (itSmallFamily != itLargeFamily)

You'll have to make sure that the iterators don't jump over each other for this to work though. That is, if itSmallFamily is only one increment away from itLargeFamily , you will simply swap them over and they'll never have been equal to each other.

You could instead use std::vector , whose iterators are random access iterators. In addition, std::array and std::deque are also support random access.

From the comments and the answer of sftrabbit you can see that relational operators are only defined for random access iterators, and std::list has only bidirectional iterators. So there are several solutions for your problem:

  1. Use std::vector or std::array . They provide random access iterators, have better performance for smaller sizes, and depending of how you fill/use them for larger sizes as well, and they have better memory footprint. This is the preferred solution, I'd call it the "default" solution. Use other containers only if there is a very good, measurable reason (eg a profiler tells you that using that container is a performance bottleneck).
  2. Since you know the size of the list, you can use a counter for your iterations:

     for (size_t i = 0, count = families.size()/2; i < count; ++i, --itSmallFamily, ++itLargeFamily) { /* do stuff */ }
  3. Since your list is sorted, you can compare the elements the iterators point to instead of the iterators themselves.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM