#3221
Commit `b710039` breaks tests with overloaded `operator==`
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
0No activity yet.