std::equal - cppreference.com

Defined in header

<algorithm>

template<classInputIt1,classInputIt2>boolequal(InputIt1first1,InputIt1last1,InputIt2first2); (1)(constexpr since C++20)template<classInputIt1,classInputIt2,classBinaryPred>boolequal(InputIt1first1,InputIt1last1,InputIt2first2,BinaryPredp); (2)(constexpr since C++20)template<classInputIt1,classInputIt2>boolequal(InputIt1first1,InputIt1last1,InputIt2first2,InputIt2last2); (3)(since C++14)
(constexpr since C++20)template<classInputIt1,classInputIt2,classBinaryPred>boolequal(InputIt1first1,InputIt1last1,InputIt2first2,InputIt2last2,BinaryPredp); (4)(since C++14)
(constexpr since C++20)template<classExecutionPolicy,classForwardIt1,classForwardIt2>boolequal(ExecutionPolicy&&policy,ForwardIt1first1,ForwardIt1last1,ForwardIt2first2); (5) (since C++17)template<classExecutionPolicy,classForwardIt1,classForwardIt2,classBinaryPred>boolequal(ExecutionPolicy&&policy,ForwardIt1first1,ForwardIt1last1,ForwardIt2first2,BinaryPredp); (6) (since C++17)template<classExecutionPolicy,classForwardIt1,classForwardIt2>boolequal(ExecutionPolicy&&policy,ForwardIt1first1,ForwardIt1last1,ForwardIt2first2,ForwardIt2last2); (7) (since C++17)template<classExecutionPolicy,classForwardIt1,classForwardIt2,classBinaryPred>boolequal(ExecutionPolicy&&policy,ForwardIt1first1,ForwardIt1last1,ForwardIt2first2,ForwardIt2last2,BinaryPredp); (8) (since C++17)Checks whether the two target ranges [first1, last1) and [first2, last2) are equal. For overloads without the last2 parameter, last2 is std::next(first2,std::distance(first1,last1).

1,3) Elements are compared using operator==.

2,4) Elements are compared using the given binary predicate p.

5-8) Same as (1-4), but executed according to policy.

These overloads participate in overload resolution only if the value of the following expression is true:

std::is_execution_policy_v<std::decay_t<ExecutionPolicy>>

(until C++20)std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>>

(since C++20)Parameters

first1, last1 - the pair of iterators defining the first target

range

first2, last2 - the pair of iterators defining the second target

range

p - binary predicate which returns ​true if the elements should be treated as equal. The signature of the predicate function should be equivalent to the following:

boolpred(constType1&a,constType2&b);

While the signature does not need to have const&, the function must not modify the objects passed to it and must be able to accept all values of type (possibly const) Type1 and Type2 regardless of

value category

(thus, Type1& is not allowed, nor is Type1 unless for Type1 a move is equivalent to a copy(since C++11)).
The types Type1 and Type2 must be such that objects of types InputIt1 and InputIt2 can be dereferenced and then implicitly converted to Type1 and Type2 respectively. ​

policy - the

execution policy

to use Type requirements -InputIt1, InputIt2 must meet the requirements of

LegacyInputIterator

. -ForwardIt1, ForwardIt2 must meet the requirements of

LegacyForwardIterator

. -BinaryPred must meet the requirements of

BinaryPredicate

. Return value

If the two target ranges have the same size, and each corresponding elements in the two ranges are equal, returns true. Otherwise returns false.

Complexity

Given N1 as std::distance(first1,last1) and N2 as std::distance(first2,last2):

1) At most N1 comparisons using operator==.

2) At most N1 applications of p.

3) At most min(N1,N2) comparisons using operator==.

4) At most min(N1,N2) applications of p.

5)𝓞(N1) comparisons using operator==.

6)𝓞(N1) applications of p.

7)𝓞(min(N1,N2)) comparisons using operator==.

8)𝓞(min(N1,N2)) applications of p.

If both InputIt1 and InputIt2 (or ForwardIt1 and ForwardIt2 for parallel overloads) meet the requirements of

LegacyRandomAccessIterator

, and N1≠N2, then no comparison will be made.

Exceptions

5-8) During the execution process:

If the temporary memory resources required for parallelization are not available,

std::bad_alloc

is thrown.

If an uncaught exception is thrown while accessing objects via an algorithm argument, the behavior is determined by the execution policy (for

standard policies

,

std::terminate

is invoked).

Possible implementation

equal (1)

template<classInputIt1,classInputIt2>constexpr//< since C++20boolequal(InputIt1first1,InputIt1last1,InputIt2first2){for(;first1!=last1;++first1,++first2)if(!(*first1==*first2))returnfalse;returntrue;}

equal (2)

template<classInputIt1,classInputIt2,classBinaryPred>constexpr//< since C++20boolequal(InputIt1first1,InputIt1last1,InputIt2first2,BinaryPredp){for(;first1!=last1;++first1,++first2)if(!p(*first1,*first2))returnfalse;returntrue;}

equal (3)

namespacedetail{// random-access iterator implementation (allows quick range size detection)template<classRandomIt1,classRandomIt2>constexpr//< since C++20boolequal(RandomIt1first1,RandomIt1last1,RandomIt2first2,RandomIt2last2,std::random_access_iterator_tag,std::random_access_iterator_tag){if(last1-first1!=last2-first2)returnfalse;for(;first1!=last1;++first1,++first2)if(!(*first1==*first2))returnfalse;returntrue;}// input iterator implementation (needs to manually compare with “last2”)template<classInputIt1,classInputIt2>constexpr//< since C++20boolequal(InputIt1first1,InputIt1last1,InputIt2first2,InputIt2last2,std::input_iterator_tag,std::input_iterator_tag){for(;first1!=last1&&first2!=last2;++first1,++first2)if(!(*first1==*first2))returnfalse;returnfirst1==last1&&first2==last2;}}template<classInputIt1,classInputIt2>constexpr//< since C++20boolequal(InputIt1first1,InputIt1last1,InputIt2first2,InputIt2last2){details::equal(first1,last1,first2,last2,typenamestd::iterator_traits<InputIt1>::iterator_category(),typenamestd::iterator_traits<InputIt2>::iterator_category());}

equal (4)

namespacedetail{// random-access iterator implementation (allows quick range size detection)template<classRandomIt1,classRandomIt2,classBinaryPred>constexpr//< since C++20boolequal(RandomIt1first1,RandomIt1last1,RandomIt2first2,RandomIt2last2,BinaryPredp,std::random_access_iterator_tag,std::random_access_iterator_tag){if(last1-first1!=last2-first2)returnfalse;for(;first1!=last1;++first1,++first2)if(!p(*first1,*first2))returnfalse;returntrue;}// input iterator implementation (needs to manually compare with “last2”)template<classInputIt1,classInputIt2,classBinaryPred>constexpr//< since C++20boolequal(InputIt1first1,InputIt1last1,InputIt2first2,InputIt2last2,BinaryPredp,std::input_iterator_tag,std::input_iterator_tag){for(;first1!=last1&&first2!=last2;++first1,++first2)if(!p(*first1,*first2))returnfalse;returnfirst1==last1&&first2==last2;}}template<classInputIt1,classInputIt2,classBinaryPred>constexpr//< since C++20boolequal(InputIt1first1,InputIt1last1,InputIt2first2,InputIt2last2,BinaryPredp){details::equal(first1,last1,first2,last2,p,typenamestd::iterator_traits<InputIt1>::iterator_category(),typenamestd::iterator_traits<InputIt2>::iterator_category());}Notes

std::equal should not be used to compare the ranges formed by the iterators from

std::unordered_set

,

std::unordered_multiset

,

std::unordered_map

, or

std::unordered_multimap

because the order in which the elements are stored in those containers may be different even if the two containers store the same elements.

When comparing entire containers or string views(since C++17) for equality, operator== for the corresponding type are usually preferred.

Sequential std::equal is not guaranteed to be short-circuit. E.g. if the first pair elements of both ranges do not compare equal, the rest of elements may also be compared. Non-short-circuit comparison may happen when the ranges are compared with

std::memcmp

or implementation-specific vectorized algorithms.

Example

The following code uses

std::equal

to test if a string is a palindrome.

Run this code

#include<algorithm>#include<iomanip>#include<iostream>#include<string_view>constexprboolis_palindrome(conststd::string_view&s){returnstd::equal(s.cbegin(),s.cbegin()+s.size()/2,s.crbegin());}voidtest(conststd::string_view&s){std::cout<<std::quoted(s)<<(is_palindrome(s)?" is":" is not")<<" a palindrome\n";}intmain(){test("radar");test("hello");}Output:

"radar" is a palindrome "hello" is not a palindrome See also

ranges::equal

(C++20)

determines if two sets of elements are the same
(algorithm function object)

[edit]

findfind_iffind_if_not

(C++11)

finds the first element satisfying specific criteria
(function template & algorithm function object)

[edit]

ranges::findranges::find_ifranges::find_if_not

(C++20)(C++20)(C++20)

lexicographical_compare

compares two ranges lexicographically
(function template & algorithm function object)

[edit]

ranges::lexicographical_compare

(C++20)

mismatch

finds the first position where two ranges differ
(function template & algorithm function object)

[edit]

ranges::mismatch

(C++20)

search

searches for the first occurrence of a range of elements
(function template & algorithm function object)

[edit]

ranges::search

(C++20)

equal_range

finds the range of elements matching the given value using binary search
(function template & algorithm function object)

[edit]

ranges::equal_range

(C++20)

equal_to

function object implementing x==y
(class template)

[edit]