1

Probably a very simple question but I'm interested in what options there are. I have three conditions each of which should produce a different output

// special cases
if(!A && B)
     return -1;
if(A && !B)
     return 1;
if(!A && !B)
     return 0;

// general case
return someOtherFunction(x, y);

Which I can get down to -

if(!A) {
    if(!B)
        return 0;
     return -1;
}
if(A && !B)
    return 1;

return someOtherFunction(x, y);

Can I simplify this further? This is in C++ so I am limited to using language specific operators and functions (including STL) etc.

3
  • 3
    What do you return for A&&B? Commented May 25, 2016 at 10:56
  • I actually then call a different function to compare two object, I will edit the op Commented May 25, 2016 at 10:59
  • The first is much simpler than the second. Commented May 25, 2016 at 11:56

4 Answers 4

5
return (!A ? (!B ? 0 : -1) : (!B ? 1 : someOtherFunction(x, y)));

This is using nested ternary operator.

Sign up to request clarification or add additional context in comments.

2 Comments

What about someOtherFunction call? If A is true, and B is also true - this expression will fail to call the other function.
@Ajay Updated the answer to include the case that the OP added later. This is what happens when OP edits a question, without mentioning that it is, in fact, an edit!
4

Use look-up table:

int lookup[2][2] = {
    { 0, -1}
,   { 1,  100}
};
...
bool A, B;
A = ...
B = ...
...
int res = lookup[A][B];
// When A && B, call other function
return res != 100 ? res : someOtherFunction(a, b);

Note: If A and B are not Boolean, convert them to logical values with the double-negation trick:

return lookup[!!A][!!B];

6 Comments

No one said it should be readable ;-). @dasblinkenlight. You could add a second lookup table with bools. And write it like: return lookupBool[A][B]?lookupInt[A][B]:someOtherFunction(A, B)
Your code is overly complicated - it doesn't simplify, but complicates the code. Other solution (ternary) is simply not correct.
@Gene Readability is in the eye of the reader. To me, look-up tables are far more readable than a chain of three conditionals. This may not be the perfect example because OP has only two variables, but with three or more variables table look-up becomes clearly superior.
@Ajay Admittedly, there is very little to simplify about code with two logical variables. However, once the number of variables goes up to three or more, maintainability of if chains quickly deteriorates to the point of becoming nightmare. Lookup tables are free from this problem. They also give you a branch-free solution in situations when you do not need to call someOtherFunction.
@dasblinkenlight I totally agree. I think your code is perfectly fine. Especially because we don't know the context the whole expression will be used at the end. Also if this code is repeated in different ways at a lot of places, reducing amount of lines of code is very helpfull.
|
3

I would suggest you to keep it as is for the sake of readability and understanding by the fellow programmer (which might be you). Don't optimize unnecessarily unless really needed. In this case, you don't get any real advantage.

One thing you could do is to store result of A and B into variables (if they are function calls).

Comments

3

So interestingly the case if (A and B) is not defined.

I would use following solution, since boolean can be converted to ints.

return A - B;

Edit: the original question changed. In that case I would do:

if (!A or !B)
    return A - B;
return someOtherFunction(A, B);

6 Comments

Or with the double negation trick from @dasblinkenlight . return (!!A) - (!!B);
I quite like this as it is fairly readable but also quite elegant, my only question is whether this (implicit casting of bools for comparison) is hacky?
I'm not hundred percent sure, but it seems like the conversion from bools to ints is well defined in c++. See this answer: stackoverflow.com/a/5369783/1293111
@Madden, Yes, it is well defined. Be careful though. If A and B are not variables but function calls (it is not obvious from your question) with side effects then this code will have UB.
@DmitryKuznetsov, same goes for the call someOtherFunction(A, B) which has UB anyway, if A and B are functions and they have sideeffects that interfere with each other.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.