Reputation: 2731
there is the conditional operator x?a:b
, which often saves a lot of writing
now I found an expression like this
if ( ( isMax && lower-higher <= distance) ||
( !isMax && lower-higher >= distance) ) { ...
where isMax
is a bool defining if maximum (true) or minimum (false) is to be used, lower
and higher
are the boundaries (int in this case)
now i'm wondering: is there a way to somehow "pick" the operator this way?
I mean not the " x?a:b " way where the operand can be chosen, but to use a different operator
something like bool (*op)() = isMax ? operator<=() : operator >=
, used on lower-higher
?
or like lower-higher (isMax? <= : >=) distance
, which won't work (of course)
Upvotes: 1
Views: 92
Reputation: 41092
You can do this if you encapsulate the operators into functions with the same type:
namespace detail{
template<class T>
bool less_equal(T lhs, T rhs)
{
std::cout << "Using <=\n";
return lhs <= rhs;
}
template<class T>
bool greater_equal(T lhs, T rhs)
{
std::cout << "Using >=\n";
return lhs >= rhs;
}
}
And then we can write your logic as:
void DoTheThing(bool isMax, int lower, int higher, int distance)
{
auto func = isMax ? &detail::less_equal<int> : &detail::greater_equal<int>;
if (func(lower-higher, distance))
{
// your logic here
}
}
And a test:
int main()
{
DoTheThing(true, 1, 1, 1); // <=
DoTheThing(false, 1, 1, 1); // >=
return 0;
}
Output:
Using <=
Using >=
Upvotes: 2
Reputation: 39370
Apparently this is possible1:
(x ? [](int a, int b){ return a >= b; } : [](int a, int b){ return a <= b; })(a, b)
Should you do that, though? I'd personally just go with a (bool, int, int)
function.
1 I was a bit surprised at first, but I guess it's triggering the lambda decay somehow. If they were closures (had something within []
) they would be different types and as such the type of the ?:
would depend on runtime state.
Upvotes: 1
Reputation: 9988
Short answer: No.
But something close would be to write your own inline function with this effect:
template<class T>
inline bool compare(bool isLessThan, const T& left, const T& right)
{
if (isLessThan) {
return left <= right;
}
else {
return left >= right;
}
}
// ... later ...
if (compare(isMax, lower - higher, distance)) {
// ...
}
My opinion (which you didn't ask for): just use an intermediate variable (or several if necessary)!
Upvotes: 2
Reputation: 234655
I'm not sure the ternary conditional is of much help here. But you can save some typing (and perhaps even gain a bit of performance; profile it) by writing
(2 * isMax - 1) * (lower - higher) <= distance
This assums that isMax
is a bool
type, or is either 1 or 0. A perfect equivalent is the obtuse
(2 * !!isMax - 1) * (lower - higher) <= distance
On the grounds it took me 3 edits to get this correct, it might be encroaching on the borderline of readability.
Perhaps therefore leave it as it is, or bury the complexity in a function.
Upvotes: 1