Skip to content

UnorderedRangeEquals calls Comparator function with different argument orders #3043

@gfrontera

Description

@gfrontera

Describe the bug
When using UnorderedRangeEquals to compare two ranges of different types, the Comparator function is called assuming the order of arguments does not matter.

Let's assume that I want to compare a range of elements of type A against another range of elements of type B. I have implemented a Comparator function:
bool compareAB(const A& a, const B& b);

However, when providing that Comparator function to UnorderedRangeEquals, compilation will fail because it calls the Comparator function as compareAB(a, b) as well as compareAB(b, a), and it expects the Comparator function to work either way.

Expected behavior
UnorderedRangeEquals should call the Comparator function providing always the arguments in the same order: the first argument should correspond to an element in the first range, and the second element to an element in the second range.

Reproduction steps
This simple program triggers the error:

#include <catch2/catch_test_macros.hpp>
#include <catch2/matchers/catch_matchers.hpp>
#include <catch2/matchers/catch_matchers_range_equals.hpp>

struct A {
    int i;
};

struct B {
    int j;
};

TEST_CASE("Test") {
    std::vector<A> va = {{1},{2},{3},{4}};
    std::vector<B> vb = {{4},{2},{3},{1}};

    CHECK_THAT(va, Catch::Matchers::UnorderedRangeEquals(vb,
            [](auto v1, auto v2) {return v1.i == v2.j;}));
}

See in Compiler Explorer: https://godbolt.org/z/ajnb9468s

Platform information:

  • OS: Ubuntu 24.04
  • Compiler+version: Clang 20.1.2
  • Catch version: v3.11.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions