A ternary conditional expression a ? b : c
is an expression and is therefore not equivalent to if (a) { b } else { c }
.
Because it’s an expression, it must have a type (and, if that type is not void
, it has a value too). This is why you can put a ternary conditional on the right-hand side of an assignment (or even the left-hand side in some cases).
The type of a conditional expression is determined from the types of its second and third operands. If they have the same type, then the result is that type. If there is not some “unambiguous” type that both operand types can be converted to, then the ternary expression does not default to a void
results; it instead results in a compilation error.
In your case, the two operands are:
(this->start = start)
(cerr << "Start cannot be higher than end." << endl)
The former has, I assume, some numeric type (the type of this->start
) while the latter has std::ostream&
type. There is no canonical “common type” of these two types, or in other words, the ternary operator has no “obvious” result type and a compilation error occurs.
An if
statement would solve this problem. If you insist on using a conditional operator, you can do so like this:
(start <= this->end)
? void(this->start = start)
: void(cerr << "Start cannot be higher than end." << endl);
Here, both the second and third expressions are cast to void
and the entire ternary expression therefore has result type void
.
Note that you can’t have something like break
or return
as one of the operands. condition ? void(return foo) : void(return bar)
will not work, because return <expr>
is a statement, not an expression. It has no type, not even void
. In this case, you can only use an if
statement. However, you can throw
inside a conditional expression since throw <expr>
is an expression.
CLICK HERE to find out more related problems solutions.