Beginner's Guide

# Standard Library Range ComparisonsRange ComparisonsCompare

## `equal`equal

uses `operator ==` for comparing elements; alternatively a custom function(object) can be passed as additional argument

``````#include <vector>
#include <iostream>
#include <algorithm>

int main () {std::vector<int> r1 {0,1,2,3,4,5,6,7,8,9};
std::vector<int> r2 {1,2,3,4,5,6,0,0};
// compare subranges (as shown in image):
std::cout << equal(begin(r1)+2, begin(r1)+7, begin(r2)+1) << '\n';  // true
// compare entire containers:
std::cout << equal(begin(r1), end(r1), begin(r2)) << '\n';  // false
// compare other subranges:
std::cout << equal(begin(r1)+1, begin(r1)+7,               begin(r2), begin(r2)+6) << '\n';  // true
// custom type
struct P { int x; char q; };
std::vector<P> a { P{1,'n'}, P{2,'m'} };
std::vector<P> b { P{1,'y'}, P{2,'z'} };
// compare 'P's only by member 'x'
std::cout << equal(begin(a),end(a), begin(b),end(b),
[](P p1, P p2) { return p1.x == p2.x; } ) << '\n';  // true
}``````

uses `operator ==` for comparing elements; alternatively a custom function(object) can be passed as third argument

``````#include <vector>
#include <iostream>
#include <algorithm>

int main () {std::vector<int> range1 {2,3,4,5,6};
std::vector<int> range2 {2,3,4,5,6};
// compare subranges (as shown in image):
std::cout << std::ranges::equal(range1, range2) << '\n';  // true
}``````

## `mismatch → {@in1,@in2}`mismatch

returns a `std::pair` of iterators to the first mismatching elements in 2 ranges

uses `operator ==` for comparing elements; alternatively a custom function(object) can be passed as additional argument

``````#include <vector>
#include <iostream>
#include <algorithm>

int main () {std::vector<int> r1 {0,1,2,3,4,5,6,7,8,9};
std::vector<int> r2 {1,2,3,4,5,7,8,8};
// compare subranges (as shown in image):
auto p = mismatch(begin(r1)+2, begin(r1)+9, begin(r2)+1);
// != end-of-range ⇒ mismatch
if (p.first  != begin(r1)+9) { auto p1value = *p.first;  std::cout << "p1value: " << p1value << '\n'; }  // 6
if (p.second != end(r2))     { auto p2value = *p.second; std::cout << "p2value: " << p2value << '\n'; }  // 7
// compare entire containers:
auto q = mismatch(begin(r1), end(r1), begin(r2));
if (q.first != end(r1)) {
auto q1value = *q.first;  // 0
auto q1index = distance(begin(r1), q.first);  // 0
std::cout << "-----------------------\n";
std::cout << "q1value: " << q1value << '\n';
std::cout << "q1index: " << q1index << '\n';
std::cout << "-----------------------\n";}
if (q.second != end(r2)) {
auto q2value = *q.second;  // 1
auto q2index = distance(begin(r2), q.second);  // 0
std::cout << "q2value: " << q2value << '\n';
std::cout << "q2index: " << q2index << '\n';}
}``````

uses `operator ==` for comparing elements; alternatively a custom function(object) can be passed as additional argument

``````#include <vector>
#include <iostream>
#include <algorithm>

int main () {std::vector<int> range1 {1,5,4,6,3};
std::vector<int> range2 {1,5,4,7,3};
auto [p1,p2] = std::ranges::mismatch(range1, range2);
auto const value1 = *p1;  // 6
auto const value2 = *p2;  // 7
std::cout << "value1: " << value1 << '\n';
std::cout << "value2: " << value2 << '\n';}``````

## `lexicographical_compare`lex.compare

uses `operator <` for comparing elements; alternatively a custom function(object) can be passed as additional argument

``````#include <vector>
#include <iostream>
#include <algorithm>

int main () {std::string r1 = "xalgori";
std::string r2 = "abced";
// compare subranges (as shown in image):
std::cout << lexicographical_compare(  begin(r1)+1, begin(r1)+5,                                  begin(r2)+1, begin(r2)+4) << '\n';  // true (r1 before r2)
// compare entire containers:
std::cout << lexicographical_compare(  begin(r1), end(r1),                                  begin(r2), end(r2)) << '\n';  // false (r1 after r2)
// strings are actually already comparable:
std::cout << (r1 < r2) << '\n';  // false
std::cout << (r1 > r2) << '\n';  // true (r1 after r2)
// custom type
struct P { int x; int y; };
std::vector<P> a { P{1,9}, P{2,9} };
std::vector<P> b { P{1,8}, P{3,8} };
// compare 'P's only by member 'x'
std::cout << lexicographical_compare(begin(a),end(a), begin(b),end(b),
[](P p1, P p2) { return p1.x < p2.x; } ) << '\n';  // true
}``````

uses `operator <` for comparing elements; alternatively a custom function(object) can be passed as additional argument

``````#include <vector>
#include <iostream>
#include <algorithm>

int main () {std::vector<char> range1 = {'a','l','g','o'};
std::vector<char> range2 = {'b','c','e'};
std::cout << std::ranges::lexicographical_compare(range1, range2) << '\n';  // true
std::cout << std::ranges::lexicographical_compare(range1, range2, std::greater<>{}) << '\n';  // false
}``````

## `lexicographical_compare_three_way`lexicogr.comp.3wayC++20

compares two ranges using 3-way comparisons and returns the result as a value of the strongest applicable comparison category (`std::::strong_ordering`, `std::::weak_ordering` or `std::::partial_ordering`)

``````#include <string>
#include <iostream>
#include <algorithm>

int main () {std::string r1 = "xalgori";
std::string r2 = "abced";
// compare subranges (as shown in image):
auto const lcA = lexicographical_compare_three_way(
begin(r1)+1, begin(r1)+5,   begin(r2)+1, begin(r2)+4);
std::cout << (lcA <  0) << '\n';  // true
std::cout << (lcA == 0) << '\n';  // false
std::cout << (lcA >  0) << '\n';  // false
// compare entire strings // with C++20's 'spaceship' operator:
auto const lcB = r1 <=> r2;
std::cout << (lcB <  0) << '\n';  // false
std::cout << (lcB == 0) << '\n';  // false
std::cout << (lcB >  0) << '\n';  // true
}``````