3

Consider this const declaration of int num:

int main() {
    bool a = true, b = false;
    // ...
    const int num = a ? (b? 2 : 4) : 4;
    std::cout << num;
}

What I want is for const int num to follow this truth table (which I apologize has been edited from my original question to reflect the pattern in my program):

              b
  a      true   false
true      2      4
false     4      2

How to modify the above const int num declaration to achieve this using the ternary operator? I know how to declare such num to be const using a lambda function and nested if-statements or switch statenents within the lambda function, but I just wanted to know how to do it using the ternary operator. As a bonus, what if 3 or more such bool values were to be used (with no specific pattern in the truth table)?

prestokeys
  • 4,817
  • 3
  • 20
  • 43

4 Answers4

6
const int num = a ? (b? 2 : 3) : (b? 4: 5);

EDIT:

As a bonus, what if 3 or more such bool values were to be used?

I wouldn't use such syntax at all. I would declare my table as

int truthTable[2][2]..[2] = {{..},...{..}}

and now simply:
int res = truthTable[!true][!false]..[!true]

!true will become 0 , !false will become 1, then, the right value will be pulled from the array.

David Haim
  • 25,446
  • 3
  • 44
  • 78
  • Is `b` evaluated once or twice here? Any way to write `b` just once? – prestokeys Jun 28 '15 at 14:33
  • 1
    I don't know, I think the compiler will either not optimize at all , optimize partially or completly optimize away the code. therefore- we can't know. – David Haim Jun 28 '15 at 14:34
  • Look at the generated assembly to know. – Hatted Rooster Jun 28 '15 at 14:41
  • @ David Haim. Would you recommend declaring a (static) truthTable 2-d array for the 2-bools case? At the cost of just a few bytes of memory, we may perhaps optimize better? – prestokeys Jun 28 '15 at 14:46
  • 1
    It depends. is size is your problem? speed? lines of code? I think you should specify your real problem in order to get a real answer – David Haim Jun 28 '15 at 14:47
  • 1
    @prestokeys Just to clarify, it appears that gcc is not evaluating `b` twice with the `-O2` and `-O3` switches. It's doing something quite neat, [view it here](http://goo.gl/ew1LIR) if you'd like! – Alejandro Jun 28 '15 at 15:00
6

David Haim's answer is great for lots of other values in the truth table. In this specific instance however, there is an easily identifiable mathematical relationship we can make use of:

const int num = (a ? 2 : 4) + (b ? 0 : 1);

We may not always have such an easily identifiable relationship in the truth table though.


The above expression was based on the question's original truth table, which looked like this:

              b
  a      true   false
true      2      3
false     4      5

Given this truth table:

b a true false true 2 4 false 4 2

There's another way we can return the correct values for this one:

const int num (a == b) ? 2 : 4

This one isn't really any sort of math. It's just simply recognizing that when a and b are the same, we want 2, but when a and b are different, we want 4. This truth table is exactly the same as the truth table for the == operator, we're just returning 2/4 instead of true/false.

nhgrif
  • 61,578
  • 25
  • 134
  • 173
  • @ nhgrif. I edited my question to reflect the actual pattern in my program. So the 2,4 is flipped when b is false. What's the mathematical relationship we can make use of then to write b just once? – prestokeys Jun 28 '15 at 14:43
3

You can write the declaration like

const int num = ( a ^ b ) ? 4 : 2;

At least it is more clear than

const int num = a ? (b? 2 : 4) : 4;

Here is a demonstrative program

#include <iostream>

int main()
{
    std::cout << ( false ^ false ? 4 : 2 ) << std::endl;
    std::cout << ( true  ^ false ? 4 : 2 ) << std::endl;
    std::cout << ( false ^ true  ? 4 : 2 ) << std::endl;
    std::cout << ( true  ^ true  ? 4 : 2 ) << std::endl;
}

The program output is

2
4
4
2
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
1

Well in this particular case I would go for:

const int num = (a == b) ? 2 : 4;
bolov
  • 72,283
  • 15
  • 145
  • 224