5

I'm trying to use a conditional statement that does one thing in one condition but does two things if the other condition applies.

Consider the following:

 ( h >= 0 && h < 24 ? hour = h : hour = 0, cout << "Invalid Hour Detected\n")

If "h" is set to 25, it sets "hour" to 0 correctly. If "h" is set to 12, it correctly sets "hour" to 12.

The problem is that it outputs "Invalid Hour Detected" for both true and false conditions. I only want it to output if the conditions aren't met.

Essentially, I'm wondering if it is possible in a conditional statement to do two things for one condition.

Also tried:

( h >= 0 && h < 24 ? hour = h : hour = 0 && cout << "Invalid Hour Detected\n")

but that didn't run the cout on either case.

5
  • This happened to someone else not long ago. You'll have to switch the order and add brackets. Commented May 21, 2013 at 18:19
  • Care to elaborate on how/where? I looked for this issue and couldn't find anything similar. Commented May 21, 2013 at 18:23
  • This might help. Commented May 21, 2013 at 18:24
  • 1
    This kind of stuff obfuscates your code. I would recommend not using it. Commented May 21, 2013 at 18:25
  • You have used &&. When hour = 0, the expression is false and cout statement will not get evaluated. Commented May 21, 2013 at 18:35

5 Answers 5

13

If you really want to do this, add proper parentheses and invert the order of the assignment and the output insertion (when using the comma operator, the value of the left expression is discarded):

( h >= 0 && h < 24 ) ? ( hour = h ) : (std::cout << "Invalid Hour Detected\n", hour = 0);

However, my advice is to make your code readable and abandon this kind of coding style.

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

4 Comments

@Steve 'Kepano' Eggering, This is what I was getting at. The types have to be consistent at least.
Thanks, I am going back to an if/else.
@Steve'Kepano'Eggering: Wise decision
"when using the comma operator, the value of the left expression is discarded" : could you explain a little bit more please or give a source ?
4

I'm trying to use a conditional statement that does one thing in one condition but does two things if the other condition applies.

That's not a conditional statement, it's a conditional expression+. Conditional statement would be a lot more appropriate here from the readability perspective:

if( h >= 0 && h < 24) {
    hour = h;
} else {
    hour = 0;
    cout << "Invalid Hour Detected\n";
}


+ C++ follows C in allowing use of standalone expressions as statements. That's why you can eventually "shoehorn" your solution into the right syntax by using parentheses and switching the order of operations. The readability of that solution suffers a lot compared to that of a plain, familiar if.

1 Comment

That's what I had originally, was just curious if there was a way to one line it.
0

Try

( h >= 0 && h < 24 ? hour = h : (hour = 0 || cout << "Invalid Hour Detected\n"))

Or

( h >= 0 && h < 24 ? hour = h : (hour = 0 & cout << "Invalid Hour Detected\n"))

Comments

0

The comma operator has the lowest precedence of all the operators. Consequently, your expression is evaluated like this:

(( h >= 0 && h < 24 ? hour = h : hour = 0), cout << "Invalid Hour Detected\n") 

You could express this in a conditional expression, with grouping and proper usage of the comma operator. But, if at all possible, it would be better to express this in an if/else statement. If you need to use it in an expression, consider placing it in a function.

Comments

0

Well I know that this is probably not the answer you are looking for but if you refactored a little this would be cleared up "naturally".

// Handy as a utility free function (in apt namespace)
bool isValidHour(unsigned int hour) { 
    return hour >= 0 && hour < 24;
}

isValidHour(h) ? hour = h : handleInvalidHour();
//...more

// If this is not in a class then you should pass "hour" as a reference.
void MyClass::handleInvalidHour() { 
    hour = 0;
    cout << "Invalid Hour Detected\n";
}

Of course you should be using the new std::chrono stuff if possible. It's lovely and expressive.

Comments

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.