Catch Classic used to provide somewhat better error, as it would error
out during instantion of a type named something along the lines of
CATCH_STATIC_ASSERT_EXPRESSION_TOO_COMPLEX_REWRITE_...
, but apparently
that went away during the rewrite of expression capture layer.
Anyway, the simple answer was already provided by user463035818, enclose
the expression in parentheses. I want to expand on why expressions containing
operators &&
or ||
are not supported.
There are three parts to why &&
and ||
operators are not supported,
two of them are practical, and one is philosophical.
1) The TMP magic used to decompose the expression and pretty-print it
cannot properly emulate short-circuiting behaviour of the built-in operators.
This means that the behaviour of such expressions would be different from
user's expectations.
2) The already mentioned TMP magic is fairly expensive in regards to
compile times, even though we have specialized paths for unary and binary
expressions. Having a general path for variadic expressions would likely
end up being prohibitively expensive.
3) The use of ||
in an assertion is usually a code (test) smell. In
a reasonable unit test, you should be able to express the expected result
exactly, and for cases where this is not true (e.g. iterating through
an unordered set), logical or still isn't a good tool solution.
Note 1: Using &&
(logical and) in a unit test is completely reasonable
and in fact it is fairly trivial to rewrite an expression using &&
to compile and still shortcircuit:
REQUIRE((expr1 && expr2 && expr3));
REQUIRE(expr1);
REQUIRE(expr2);
REQUIRE(expr3);
Note 2: This started out as a comment to the other answer, but then it
went over the allowed length and I noticed that the error message for
Catch2 is indeed bad, so I opened up an issue.