The following C++23 code does not compile with gcc:
#include <ranges>
#include <iostream>
#include <vector>
int main() {
std::vector<int> v1{1,2,3,4};
std::vector<int> v2{2,4,6,8};
auto z = std::views::zip(v1, v2);
if(std::ranges::find(z, {2, 4}) != z.end()) {
std::cout << "(2,4) in zip\n";
}
return 0;
}
The error is:
zip.cpp:11:25: error: no match for call to ‘(const std::ranges::__find_fn) (std::ranges::zip_view<std::ranges::ref_view<std::vector<int, std::allocator<int> > >, std::ranges::ref_view<std::vector<int, std::allocator<int> > > >&, <brace-enclosed initializer list>)’
If I change the code as follows:
#include <ranges>
#include <iostream>
#include <vector>
int main() {
std::vector<int> v1{1,2,3,4};
std::vector<int> v2{2,4,6,8};
auto z = std::views::zip(v1, v2);
if(std::ranges::find_if(z, [](auto p){return p == std::make_pair(2, 4);}) != z.end()) {
std::cout << "(2,4) in zip\n";
}
return 0;
}
The error is more comprehensible:
zip.cpp:10:52: error: no match for ‘operator==’ (operand types are ‘std::pair<int&, int&>’ and ‘std::pair<int, int>’)
Is there a way to make similar code compile? To be clear, what I want to achieve is to verify if a pair of elements is in a zip view. I.e., if the first element is in the first vector, the second element is in the second vector, and their indices are equal.
Your code tries to compare a pair<int,int>
with a pair<int&,int&>
. It should be OK, however it seems that none of the mainstream compilers have conforming implementations of operator==
for pairs yet.
Published standards used to specify
template<class T1, class T2>
constexpr bool operator==(const pair<T1,T2>&, const pair<T1,T2>&);
which is what all current implementations do. However a relatively new defect report changes this to
template<class T1, class T2, class U1, class U2>
constexpr bool operator==(const pair<T1,T2>&, const pair<U1,U2>&);
which fixes the problem. It has not made its way into the compilers yet.
You will have to provide your own custom comparator until the implementations catch up with the DR.