Tommylee2k
Tommylee2k

Reputation: 2731

conditional operator for operations?

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

Answers (4)

AndyG
AndyG

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 >=

Demo

Upvotes: 2

Bartek Banachewicz
Bartek Banachewicz

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

Arthur Tacca
Arthur Tacca

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

Bathsheba
Bathsheba

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

Related Questions