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", *B = "B", *C = "C", *D = "D", *E = "E", *F = "F", *G = "G";
Now let's say I want to behave in a particular way if the result of some expression is in a subset of those:
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)
{
...
}
I find myself typing this sort of thing often enough that I would like a shorthand for it.
If the language was Python, I could easily say:
if some_complicated_expression_with_ugly_return_type in [A, C, E, G]:
...
Is there a well-known, portable way for me to express this similarly in C++03?
Note that the return type is itself ugly (almost as ugly as the return type of lambda expressions), so I certainly don't want to store it in a local variable.
But the return type does not have to match that of the constants -- for example, if the return type was std::string
, it would not be implicitly convertible to const char *
, but operator ==
would be perfectly fine for the comparison.
So far, the best solution I have is to say something like:
const char *items[] = { A, C, E, G };
if (std::find(items, items + sizeof(items) / sizeof(*items),
some_complicated_expression_with_ugly_return_type)
!= items + sizeof(items) / sizeof(*items))
{
...
}
but it's pretty darn ugly. Is there a better way, which also works for non-PODs?
Foo (pronounced FOO) is a term used by programmers as a placeholder for a value that can change, depending on conditions or on information passed to the program. Foo and other words like it are formally known as metasyntactic variables.
The logical OR ( || ) operator (logical disjunction) for a set of operands is true if and only if one or more of its operands is true. It is typically used with boolean (logical) values.
The *= operator first multiplies the value of the expression (on the right-hand side of the operator) by the value of the variable or property (on the left-hand side of the operator). The operator then assigns the result of that operation to the variable or property.
The addition assignment operator ( += ) adds the value of the right operand to a variable and assigns the result to the variable.
If you have C++11:
auto res = some_complicated_expression_with_ugly_return_type;
if (res == A
|| res == C
|| res == E
|| res == G) {
}
if not, you can still eliminate the type declaration by using a template function:
template <class T>
bool matches(T t) {
return t == A || t == C || t == E || t == G;
}
if (matches(some_complicated_expression_with_ugly_return_type)) {
}
You could factor your current best solution into a template:
template<class A, class B, size_t n>
inline bool is_in(const A &a, B (&bs)[n]) {
return std::find(bs, bs + n, a) != bs + n;
}
which you can use like
X items[] = { A, C, E, G };
if (is_in(some_complicated_expression_with_ugly_return_type, items))
…
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With