Where in C++ is Required to Use Conditional Expression (?:) - c++

I have a book that teaches C++ programming. In the book, it says "Conditional expressions can appear in some program locations where if…else statements cannot" The book doesn't specify where.
I was curious if someone can show me an example where you explicitly MUST use conditional statement and not if...else statement.
Thanks,

In general, where language expects an expression. There are several cases where ?: operator cannot be easily replaced with if statement. It rarely occurs in practice, but it is possible. For example:
const int x = (a > 0) ? a : 0; // (global) const/constexpr initialization
struct D: public B {
D(int a)
: B(a > 0 ? a : 0) // member initializer list
{ }
};
template<int x> struct A {
};
A<(a>0) ? a : 0> var; // template argument

A conditional expression is an expression, whereas an if-else is a statement. That means you can embed conditional expressions in other expressions, but you can't do that with if-else:
// works
x = flag ? 5 : 6;
// meaningless nonsense
x = if (flag) 5 else 6;
You can always rewrite the code to use if-else, but it requires restructuring the logic a bit.

'to initialize a constant variable depending on some expression' - says https://stackoverflow.com/a/3565387/3969164

You can use the ternary operator in an expression, not just on statements. For example,
bool foo;
if (bar)
foo = false;
else
foo = true;
can be shortened to
bool foo = (bar)?false:true;
It's never necessary to perform an action, and just exists for convenience.

Related

What does '?' mean in this statement of C++? [duplicate]

I've always wondered how to write the "A ? B : C" syntax in a C++ compatible language.
I think it works something like: (Pseudo code)
If A > B
C = A
Else
C = B
Will any veteran C++ programmer please help me out?
It works like this:
(condition) ? true-clause : false-clause
It's most commonly used in assignment operations, although it has other uses as well. The ternary operator ? is a way of shortening an if-else clause, and is also called an immediate-if statement in other languages (IIf(condition,true-clause,false-clause) in VB, for example).
For example:
bool Three = SOME_VALUE;
int x = Three ? 3 : 0;
is the same as
bool Three = SOME_VALUE;
int x;
if (Three)
x = 3;
else
x = 0;
It works like this:
expression ? trueValue : falseValue
Which basically means that if expression evaluates to true, trueValue will be returned or executed, and falseValue will be returned or evaluated if not.
Remember that trueValue and falseValue will only be evaluated and executed if the expression is true or false, respectively. This behavior is called short circuiting.
In c++ there's no actual if part of this. It's called the ternary operator. It's used like this: <boolean statement> ? <result if true> : <result if false>; For your example above it would look like this:
C = A > B ? A : B;
This article on wikipedia also discusses it:
http://en.wikipedia.org/wiki/Ternary_operation
I assume you mean stuff like a = b ? c : d, where b is the condition, c is the value when b is true, and d is the value when b is false.
I would say the ? is a short-cut. However, some "hard-core" programmers tend to say write it out the long way so in future cases, people can easily read and modify code.
For example, if you write
int a = b<c ? b : c;
Some people claim that it's clearer to write:
if(b<c)
a = b;
else
a = c;
Because in future cases, people can catch it. Of course, a simple b<c ? b:c is easy to catch, but sometimes complex operations are put in and it can be hard to spot.
No one seems to mention that a result of conditional operator expression can be an L-value in C++ (But not in C). The following code compiles in C++ and runs well:
int a, b;
bool cond;
a=1; b=2; cond=true;
(cond? a : b) = 3;
cout << a << "," << b << endl;
The above program prints 3, 2
Yet if a and b are of different types, it won't work. The following code gives a compiler error:
int a;
double b;
bool cond;
a=1; b=2; cond=true;
(cond? a : b) = 3;
cout << a << "," << b << endl;
IT IS QUITE SIMPLE
IT'S BASIC SYNTAX IS:
expression1?expression2:expression3;
If expression 1 is hold true then expression 2 will hold otherwise expression 3 will hold.
example:
hey=24>2?24:34;
here as condition is true value of 24 will be assigned to it.
if it was false then 34 will be assigned to it
simply you can write this as
C=(A>B)?A:B;
THIS IS SAME AS:
if(A>B)
C=A;
else
C=B;
This is called a "Ternary operator", and the ? and : are another way of writing an if-else statement.
Look at the "Example #1" in this Codepen, and un-comment it... you'll notice what it does.
Now comment "Example #1", un-comment "Example #2", and see what happens. The code does the exact same thing... but this time with only 5 lines of code. Notice how whatever appears before the ? sign is the if (conditional), and whatever comes AFTER the : is the thing to be executed.
But what if you have a conditional that requires an "else-if" (with more than 2 possible outcomes) like the one in the Codepen's "Example #3" (which adds the possibility of the user writing a specific wrong answer)? Then the ternary operator might not be as useful, but you can certainly concatenate several conditions with the ternary operator, like on this ES6 fizzbuzz example.
like this is our condition -> A?B:C
So according to the condition if 'A' is True then it prints 'B' or if 'A' is false it prints 'C'.
In other words we can also say that it is an alternative way of if else condition.

Why is the following code illegal in C++ [duplicate]

This question already has answers here:
Declaring and initializing a variable in a Conditional or Control statement in C++
(9 answers)
Closed 7 years ago.
I want to create an if where a variable is declared, assigned and checked. If the variable's value is acceptable, I want to use it inside if body. Here's an example of how I thought I could do that:
if ((int result = Foo()) != 0) {
// use result
}
I assumed that Foo() returns some value, which is assigned to result, and returned by assignment operator =, and finally checked against 0 in != 0. Unfortunately, it results in a compilation error:
main.cpp:31:10: error: expected primary-expression before ‘int’
if ((int i = Foo()) != 0)
^
main.cpp:31:10: error: expected ‘)’ before ‘int’
Why is this error happening? And what ways could there be to fix it?
The logic is supported, but declaring a variable within an if statement and using it this way is not. The reason is related to the fact that an initializer works differently than a regular assignment, but working around this is easy and trivial.
Just do something like this instead.
int result;
if ((result = Foo()) != 0) {
// use result
}
Your reasoning seems to be based on the assumption that = in
if ((int result = Foo()) != 0)
is an assignment operator and that int result = Foo() is "just an expression" that evaluates to something.
This is not true.
The int result = Foo() part is not an expression in C++. It is a declaration with an initializer. The = in initializer syntax is not an assignment operator at all. It is just a syntactic element that coincidentally uses the same character as assignment operator. The int result = Foo() is not an expression and it does not "evaluate" to any result.
Because if the above, support for something like
if (int result = Foo())
requires special treatment, which severely limits the flexibility of this syntax. What you tried in your code goes outside the bounds of what's allowed by that special treatment.
Bjarne uses this construct as a scope restrictor in 6.3.2.1 The C++ programming language as a recommendation.
Use:
if (int result = Foo()) {
// use non-zero result
}
It is particularly useful with pointers
if (Foo* result = GetFoo()) {
// use valid Foo
}
The !=0 part is redundant as truthiness is !=0.
The extended construct with the comparison is not allowed.
Further discussion of this construct from here
It fails because it's illegal. It's also ugly. #Jonathan Wood suggested declaring the variable outside the if. I suggest calling Foo outside, too:
int result = Foo();
if(result!=0) ...
The (x=f())!=y construct, while legal as an if condition, only makes sense in a loop, where
`while((c=getchar())!='\n)
... do something with c ...
Is the shorter and nicer equivalent of
c = getchar();
while(c!='\n')
{
...
c = getchar(c);
}
It saves writing the call to getchar() twice. It saves nothing when used in an if, so there's no point in using it.
Try this:
if ( int i = (Foo() != 0) ? Foo() : 0 ){
cout << "Hello. Number i = " << i;
}

Ternary expression which "does nothing" (noop) if the condition is false?

Out of curiosity I started wondering if it's possible to have a ternary expression that, if it evaluates to false, does nothing in the false branch.
Ie is there a way to write something like this:
variable = (someBool) ? i : <do nothing>;
As opposed to:
if (someBool) {
variable = i;
}
I tried ((void)0) or while(false){}; as no-op but the compiler expects an expression.
UPDATE:
I realized the question lost some meaning because I tried to make the code easier. The initial idea I had was to initialize a static var with a ternary - using the static var itself as the condition:
static int var = (var != 0) ? var = 1 : (var already initialized, do nothing);
This is assuming that uninitialized variables are initialized to 0 which is not always true (or never in release builds, not quite sure). So maybe it's a hypothetical question.
how about short-circuit?
int variable = 0;
bool cond = true; // or false
(cond && (variable = 42));
printf("%d\n", variable);
How about this:
variable = (someBool) ? i : variable ;
Though I would personally prefer the original if statement
Compilers not only expect expression, but the expression the returns type on the left side (the type of variable whatever is it). So, no you can not do that. It's not conditional execution, but variable member assignment.
These are completely different things.
In second example :
if (someBool) {
variable = i;
}
you do not assign anything, but simply execute based on condition. So in your case, where you don't want to do anything (not assign anything), the way to go is conditional execution so use simply the second case.
The format of the conditional expression is
<expression> ? <expression> : <expression>
In other words, it must have some expression.
Addressing your edit: in C99 variables of static scope are initialised to 0. However, I have never really trusted that because I've been programming in C since the K&R days.
Anyway, just initialise the variable. As the variable is static, it's only going to happen once during the whole execution time of the program.
You could do:
variable = !someBool ?: i;
Since the ?: will no-op when the if expression is true but assign i if it's false.
Note: This has only been tested in Obj-C
How about
(someBool) ? (variable = i) : NULL;
For C# says:
Syntax:
condition ? first_expression : second_expression;
And it says about first_expression and second_expression:
Either the type of first_expression and second_expression must be the same, or an implicit conversion must exist from one type to the other.
If you were to evaluate a nullable object type instead of bool, you could always write:
variable = myVar ?? i;
Hacky/cludgey/impractical - probably all 3, but for the sake of this question it's a way of omitting an 'else'.
Try: null lambda.
auto null_lambda = [](){return;};
int a = 1;
int b = 2;
vector<int> c;
a > c ? b = c.push_back(b) : null_lambda();

Can every if-else construct be replaced by an equivalent conditional expression?

(I don't have a serious need for this answer, I am just inquisitive.)
Can every if-else construct be replaced by an equivalent conditional expression using the conditional operator ?:?
Does every if-else constructs can be replaced by an equivalent conditional expression using conditional operator?
No, you've asked this backwards. The "bodies" of if/else contain statements, and it is not possible to turn every statement into an expression, such as try, while, break statements, as well as declarations. Many "statements" are really expressions in disguise, however:
++i;
blah = 42;
some_method(a,b,c);
All of these are statements which consist of one expression (increment, assignment, function-call, respectively) and could be turned into expressions within a conditional.
So, let's reverse the question, since it sounds like you really want to know how equivalent if/else statements are to ternary conditional expressions: Can every conditional expression be replaced by equivalent if/else statements? Almost all, yes. A common example is return statements:
return cond ? t : f;
// becomes:
if (cond) return t;
else return f;
But also other expressions:
n = (cond ? t : f);
// becomes:
if (cond) n = t;
else n = f;
Which starts to point to where conditional expressions cannot be easily replaced: initializations. Since you can only initialize an object once, you must break up an initialization that uses a conditional into using an explicit temporary variable instead:
T obj (cond ? t : f);
// becomes:
SomeType temp;
if (cond) temp = t;
else temp = f;
T obj (temp);
Notice this is much more tedious/cumbersome, and requires something type-dependent if SomeType cannot be default-constructed and assigned.
On the surface of it, no. The conditional operator is an expression (that is, it has a value), while if/else is a statement (thus has no value). They fulfill different "needs" within the language syntax.
However, since you can ignore expression values, and since any expression can be turned into a statement by adding a semicolon, you can essentially emulate if/else with a conditional expression and two auxiliary functions:
// Original code:
if (condition) {
// block 1
}
else {
// block 2
}
// conditional expression replacement:
bool if_block() {
// block 1
return true;
}
bool else_block() {
// block 2
return true;
}
// Here's the conditional expression. bool value discarded:
condition ? if_block() : else_block();
However, having said that, I'm not sure it's anything more than a curiosity...
No, of course not. For reasons already mentioned, and more!
#include <cstdlib>
#include <iostream>
int main()
{
if(int i = std::rand() % 2)
{
std::cout << i << " is odd" << std::endl;
}
else
{
std::cout << i << " is even" << std::endl;
}
}
Check out where is is declared. It's not an often used technique, but it can be used in situations like COM where every call returns HRESULT which is (almost always) zero on success (S_OK), non-zero on failure, so you might write something like:
if(HRESULT hr = myInterface->myMethod())
{
_com_raise_error(hr);
}
The ternary operator can't do anything analogous.
if( cond )
break;
else
a=b;
can not always be replaced by ?: operator. You can often (if not always) rethink your whole code to provide for this substitute, but generally you can't put anything that controls execution into ?:. break, return, loops, throw, etc.
In principle, yes:
if (A) B; else C
becomes
try {
A ? throw TrueResult() : throw FalseResult();
// or: throw A ? TrueResult() : FalseResult();
} catch (TrueResult) {
B;
} catch (FalseResult) {
C;
}
Compared to using procedures (which are more natural), this allows break, continue, return etc. It requires evaluation of A doesn't end with TrueResult/FalseResult but if you use those exceptions only to simulate if, it won't be a problem.
Using the conditional operator results in an expression and both potential results of the conditional operator must be 'compatible' (convertible to the same type).
An if-else construct need not even 'return' any type much less the same one from both branches.
The conditional operator expects to have both of the items following the ? be rvalues (since the result of a conditional operator is itself an rvalue) - so while I'm not entirely an expert on the C/C++ standards, my intuition would be that the following would be disallowed (or failing that, extremely poor coding style...):
(condition) ? return x : return y;
whereas the if-else version would be quite standard:
if(condition) return x;
else return y;
Now, that said, could you take any program and write a similarly functioning program that didn't use if-else? Sure, you probably could. Doesn't mean it would be a good idea, though. ;)
GCC has statement expression, using it you can rewrite if statements to equivalent ?: expressions:
if (<expression>)
<statement1>
else
<statement2>
EDIT: The void casts serves two purpose. The subexpressions in ?: must have the same type, and without the void cast the compiler may print warning: statement with no effect.
(<expression>)? (void)({<statement1>}) : (void)({<statement2>});

How do I use the conditional (ternary) operator?

I've always wondered how to write the "A ? B : C" syntax in a C++ compatible language.
I think it works something like: (Pseudo code)
If A > B
C = A
Else
C = B
Will any veteran C++ programmer please help me out?
It works like this:
(condition) ? true-clause : false-clause
It's most commonly used in assignment operations, although it has other uses as well. The ternary operator ? is a way of shortening an if-else clause, and is also called an immediate-if statement in other languages (IIf(condition,true-clause,false-clause) in VB, for example).
For example:
bool Three = SOME_VALUE;
int x = Three ? 3 : 0;
is the same as
bool Three = SOME_VALUE;
int x;
if (Three)
x = 3;
else
x = 0;
It works like this:
expression ? trueValue : falseValue
Which basically means that if expression evaluates to true, trueValue will be returned or executed, and falseValue will be returned or evaluated if not.
Remember that trueValue and falseValue will only be evaluated and executed if the expression is true or false, respectively. This behavior is called short circuiting.
In c++ there's no actual if part of this. It's called the ternary operator. It's used like this: <boolean statement> ? <result if true> : <result if false>; For your example above it would look like this:
C = A > B ? A : B;
This article on wikipedia also discusses it:
http://en.wikipedia.org/wiki/Ternary_operation
I assume you mean stuff like a = b ? c : d, where b is the condition, c is the value when b is true, and d is the value when b is false.
I would say the ? is a short-cut. However, some "hard-core" programmers tend to say write it out the long way so in future cases, people can easily read and modify code.
For example, if you write
int a = b<c ? b : c;
Some people claim that it's clearer to write:
if(b<c)
a = b;
else
a = c;
Because in future cases, people can catch it. Of course, a simple b<c ? b:c is easy to catch, but sometimes complex operations are put in and it can be hard to spot.
No one seems to mention that a result of conditional operator expression can be an L-value in C++ (But not in C). The following code compiles in C++ and runs well:
int a, b;
bool cond;
a=1; b=2; cond=true;
(cond? a : b) = 3;
cout << a << "," << b << endl;
The above program prints 3, 2
Yet if a and b are of different types, it won't work. The following code gives a compiler error:
int a;
double b;
bool cond;
a=1; b=2; cond=true;
(cond? a : b) = 3;
cout << a << "," << b << endl;
IT IS QUITE SIMPLE
IT'S BASIC SYNTAX IS:
expression1?expression2:expression3;
If expression 1 is hold true then expression 2 will hold otherwise expression 3 will hold.
example:
hey=24>2?24:34;
here as condition is true value of 24 will be assigned to it.
if it was false then 34 will be assigned to it
simply you can write this as
C=(A>B)?A:B;
THIS IS SAME AS:
if(A>B)
C=A;
else
C=B;
This is called a "Ternary operator", and the ? and : are another way of writing an if-else statement.
Look at the "Example #1" in this Codepen, and un-comment it... you'll notice what it does.
Now comment "Example #1", un-comment "Example #2", and see what happens. The code does the exact same thing... but this time with only 5 lines of code. Notice how whatever appears before the ? sign is the if (conditional), and whatever comes AFTER the : is the thing to be executed.
But what if you have a conditional that requires an "else-if" (with more than 2 possible outcomes) like the one in the Codepen's "Example #3" (which adds the possibility of the user writing a specific wrong answer)? Then the ternary operator might not be as useful, but you can certainly concatenate several conditions with the ternary operator, like on this ES6 fizzbuzz example.
like this is our condition -> A?B:C
So according to the condition if 'A' is True then it prints 'B' or if 'A' is false it prints 'C'.
In other words we can also say that it is an alternative way of if else condition.