#3221

Commit `b710039` breaks tests with overloaded `operator==`

Openmaxmittiopened 18d ago

Describe the bug I have code with a operator== overload in the global scope (it is meant to be used with classes from std::). REQUIRE assertions which use this operator at the top-level fail to compile since 3.16.1 / b710039a0848aa58bbe4e1bc270e7b0c809b676d.

Expected behavior The following code compiles and runs fine.

Reproduction steps This is a reduced example.


namespace test {
	struct S {
		int x;
	};
}

constexpr bool operator==(const test::S& lhs, const test::S& rhs)
{
	return lhs.x == rhs.x;
}

#include <catch2/catch_test_macros.hpp>

TEST_CASE("Test")
{
	REQUIRE(test::S{1} == test::S{1});
}

Platform information:

  • OS: Up-to-date Arch Linux (12/Oct/2026)
  • Compiler+version: GCC 16.2.1 20260810
  • Catch version: v3.16.1

Additional context Error message:

/usr/include/catch2/internal/catch_decomposer.hpp:345:5: error: no match for ‘operator==’ (operand types are ‘const test::S’ and ‘test::S’)
  345 |     CATCH_INTERNAL_DEFINE_EXPRESSION_EQUALITY_OPERATOR( eq, == )
      |     ^
  • there are 2 candidates
    • candidate 1: ‘template<class LhsT, class RhsT, class T> const Catch::BinaryExpr<LhsT, const RhsT&> Catch::operator==(const BinaryExpr<LhsT, RhsT>&, T)’
      /usr/include/catch2/internal/catch_decomposer.hpp:239:5:
        239 |     CATCH_INTERNAL_DEFINE_BINARY_EXPR_OPERATOR( == )
            |     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      • template argument deduction/substitution failed:
        •   ‘const test::S’ is not derived from ‘const Catch::BinaryExpr<LhsT, RhsT>’
          /usr/include/catch2/internal/catch_decomposer.hpp:345:5:
            345 |     CATCH_INTERNAL_DEFINE_EXPRESSION_EQUALITY_OPERATOR( eq, == )
                |     ^
    • candidate 2: ‘template<class LhsT, class RhsT> constexpr std::enable_if_t<((bool)std::conjunction<Catch::Detail::is_eq_comparable_impl<typename std::remove_reference<_Tp>::type&, typename std::remove_reference<_Arg>::type&, void>, std::negation<Catch::capture_by_value<typename std::remove_cv<typename std::remove_reference<_Arg>::type>::type> > >::value), Catch::BinaryExpr<LhsT, const RhsT&> > Catch::operator==(ExprLhs<LhsT>&&, RhsT&&)’
      /usr/include/catch2/internal/catch_decomposer.hpp:345:5:
        345 |     CATCH_INTERNAL_DEFINE_EXPRESSION_EQUALITY_OPERATOR( eq, == )
            |     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      • template argument deduction/substitution failed:
        •   types ‘Catch::ExprLhs<LhsT>’ and ‘const test::S’ have incompatible cv-qualifiers
          /usr/include/catch2/internal/catch_decomposer.hpp:345:5:
            345 |     CATCH_INTERNAL_DEFINE_EXPRESSION_EQUALITY_OPERATOR( eq, == )
                |     ^
/usr/include/catch2/internal/catch_decomposer.hpp:345:5: error: could not convert ‘{<expression error>, (& lhs)->Catch::ExprLhs<const test::S&>::getLhs(), Catch::operator""_sr(((const char*)"=="), 2), rhs}’ from ‘<brace-enclosed initializer list>’ to ‘std::enable_if_t<true, Catch::BinaryExpr<const test::S&, const test::S&> >’ {aka ‘Catch::BinaryExpr<const test::S&, const test::S&>’}
  345 |     CATCH_INTERNAL_DEFINE_EXPRESSION_EQUALITY_OPERATOR( eq, == )
      |     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      |     |
      |     <brace-enclosed initializer list>

Activity

0

No activity yet.