john
john

Reputation: 1383

How to express three cases with the conditional operator?

Is it possible to express the cases using the conditional operator? For Example :

 if(rval==1)
     DO THIS 1;
 else if(rval==2)
     DO THIS 2;
 else if (rval ==3)
     DO THIS 3;

Upvotes: 0

Views: 1004

Answers (9)

shengy
shengy

Reputation: 9749

if(rval == 1 ? DoThis1() : (rval == 2 ? DoThis2() : (rval == 3 ? DoThis3() : /*do nothing*/)))
{
    // The if-body.
}

But I think using the if-statment or the switch statment is more better

Upvotes: 0

Alpha01
Alpha01

Reputation: 856

#include "stdafx.h"


int _tmain(int argc, _TCHAR* argv[])
{
    int rval = 2;

    (rval==-1)? (printf("-1")) :( ((rval==2) ?(printf("2")) : ((rval ==3) ? (printf("3")) : (1)) ));

    return 0;
}

Upvotes: 0

Petar Ivanov
Petar Ivanov

Reputation: 93030

int lval = (rval==-1) ? 1 : ( (rval==2) ? 2 : 3 );

Upvotes: 0

Björn Pollex
Björn Pollex

Reputation: 76788

You can't. What you have there looks like a use-case for a switch-statement:

switch(rval) {
    case -1: DO THIS 1; break;
    case  2: DO THIS 2; break;
    case  3: DO THIS 3; break;
    default: ERROR;
}

Edit I was over-eager here. As @Luchian Grigore points out in the comments, you can do this (as he demonstrates in his answer). Note that this is also well defined for cases where one or both expressions are of the type void, as specified in §5.16/2 [expr.cond]:

If either the second or the third operand has type (possibly cv-qualified) void, then the lvalue-to-rvalue (4.1), array-to-pointer (4.2), and function-to-pointer (4.3) standard conversions are performed on the second and third operands, and one of the following shall hold:

— The second or the third operand (but not both) is a throw-expression (15.1); the result is of the type of the other and is an rvalue.

— Both the second and the third operands have type void; the result is of type void and is an rvalue.

[Note: this includes the case where both operands are throw-expressions. ]

Upvotes: 6

Luchian Grigore
Luchian Grigore

Reputation: 258608

Although this isn't the usual use for the ternary operator, this is how you do it:

( rval == 1 ) ? (expression1) : 
( rval == 2 ) ? (expression2) : 
( rval == 3 ) ? (expression3) : (default);

However, for the sake of code readability, I suggest you stick to the if statements.

Or better yet, it seems a switch would be even more appropriate here.

EDIT:

This is the code I used for the test:

void foo() {};
void goo() {}

int main()
{
   int x = 0;
   x == 0  ? foo() : x == 1 ? goo() : foo();
}

EDIT2:

For all nay-sayers - see section 5.16 - the second and third operands are expressions; section 5.16.2 deals with expressions that have type void.

Upvotes: 6

SK-logic
SK-logic

Reputation: 9715

There are many cases indeed when you need to use an expression (e.g., in a macro expanded where an expression is expected).

They're all valid, and when used wisely will improve the readability.

It is a shame that this distinction between statements and expressions exist (it is very unnatural and was not present in Algol, a grandfather of all the modern imperative structural languages), but there are non-standard extensions to leverage such an injustice: http://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html#Statement-Exprs

So, an answer to your question, using this extension, would be the following:

rval==1?({DO-THIS}):(?rval==2:({...}):...)

But make sure that the last statement of DO-THIS is always an expression yielding a value.

Upvotes: 0

David Schwartz
David Schwartz

Reputation: 182769

Like this:

    void MySwitch(int rval)
    {
             (rval==-1) ? DoThis(-1),0 :
            ((rval==2) ? DoThis(2),0 :
            ((rval==3) ? DoThis(3),0 : 0));
    }

Full Example:

    #include <stdio.h>

    void DoThis(int j)
    {
     printf("DoThis(%d)\n", j);
    }

    void MySwitch(int rval)
    {
             (rval==-1) ? DoThis(-1),0 :
            ((rval==2) ? DoThis(2),0 :
            ((rval==3) ? DoThis(3),0 : 0));
    }

    int main(void)
    {
     printf("Calling MySwitch(-1)\n");
     MySwitch(-1);
     printf("Calling MySwitch(2)\n");
     MySwitch(2);
     printf("Calling MySwitch(3)\n");
     MySwitch(3);
     printf("Calling MySwitch(4)\n");
     MySwitch(4);
    }

Output:

Calling MySwitch(-1)
DoThis(-1)
Calling MySwitch(2)
DoThis(2)
Calling MySwitch(3)
DoThis(3)
Calling MySwitch(4)

Of course, this is silly. Don't ever do this.

Upvotes: 0

RyuuGan
RyuuGan

Reputation: 792

switch ( rval ) {
  case 1 : 
    // Process for rval = 1
    ...
    break;
  case 2 : 
    // Process for rval = 2
    ...
    break;
  case 3 :
    // Process for rval = 3
    ... 
  default : 
    throw new InvalidStateException()
    // Process for all other cases.
    ...
}

Upvotes: 0

Brent Arias
Brent Arias

Reputation: 30165

That would look ugly, and defies every coding standard I've seen. Nevertheless, it would look like this:

int rval;
int foo = rval == -1 ? DoThis1() : (rval == 2 ? DoThis2() : DoThis3());

I'm assuming that rval == 3 is the only other possible option. And if that assumption is wrong, it makes this whole mess that much more a statement of DON'T DO THIS!!!

Upvotes: 0

Related Questions