Let\'s say I have a bunch of well-known values, like this (but const char * is just an example, it could be more complicated):
const char *A = \"A\"
Expressions of the type
if (some_complicated_expression_with_ugly_return_type == A ||
some_complicated_expression_with_ugly_return_type == C ||
some_complicated_expression_with_ugly_return_type == E ||
some_complicated_expression_with_ugly_return_type == G)
{
...
}
are quite common in code (well, a pre-computed expression is anyway). I think the best you can do for readability is pre-compute the expression and keep it as is.
ugly_return_type x = some_complicated_expression_with_ugly_return_type;
if (x == A ||
x == C ||
x == E ||
x == G)
{
...
}
Developers are used to this type of syntax. This makes it a whole lot easier to understand when someone else is reading your code
It also expresses what you want perfectly. There's a reason this type of syntax is so widely used in existing code - because other alternatives are worse for readability.
Of course, you could wrap the condition in a function, but only if it's reusable and it logically makes sense (besides the point IMO).