c++vectorcomparison-operatorsstd-rangeslexicographic-ordering

How to lexicographically compare two vectors in reverse order?


If I want to compare two vectors in lexicographical order, I can do as follows:

int main() {
    std::vector<int> a{0, 7, 8, 9};
    std::vector<int> b{1, 2, 3, 4};

    std::cout << std::boolalpha;
    std::cout << "a < b returns " << (a < b) << '\n';
}

But doing the same in reverse order fails to compile:

int main() {
    std::vector<int> a{3, 2, 1};
    std::vector<int> b{9, 8, 7, 6};

    std::cout << std::boolalpha;
    std::cout << "revrese a < reverse b returns " << ((a | std::views::reverse) < (b | std::views::reverse)) << '\n';
}

The latter code fails with:

<source>:23:81: error: no match for 'operator<' (operand types are 'std::ranges::reverse_view<std::ranges::ref_view<std::vector<int> > >' and 'std::ranges::reverse_view<std::ranges::ref_view<std::vector<int> > >')
   23 |     std::cout << "reverse a < reverse b returns " << ((a | std::views::reverse) < (b | std::views::reverse)) << '\n';
      |                                                       ~~~~~~~~~~~~~~~~~~~~~~~~~ ^ ~~~~~~~~~~~~~~~~~~~~~~~~~
      |                                                          |                           |
      |                                                          reverse_view<[...]>         reverse_view<[...]>

So, how to do achieve this properly?

I needed this because, I was creating a custom big integer class. In that, I was storing nodes in little endian order. Now, to compare if two integers are equal, first I compare their sizes. Then I would need to compare equal sized vectors in lexicographical order of their reverse view.


Solution

  • operator< is not defined for std::views::reverse and others. There is however a normal algorithm as normal function template for it in the standard library: std::lexicographical_compare with iterator interface and std::ranges::lexicographical_compare with range interface.

    std::cout << "revrese a < reverse b returns "
              << std::ranges::lexicographical_compare(a | std::views::reverse, b | std::views::reverse) 
              << '\n';