Restrictions of the ternary operator ?:

4

I have this piece of code:

(comprar >= 1 && comprar <= 40) ? ActualizarAsientos(Asientos, comprar) : cout << "Asiento fuera de rango";

Where the first condition is a void and the second one a text output, however the compiler (Visual Studio 2017) does not recognize it. I think you're asking me that both conditions are of the same type, or both a cout or both a void , does anyone know if that restriction exists or if I'm making some other mistake?

    
asked by ALEJANDRO SAENZ 15.04.2018 в 02:16
source

3 answers

6

The ternary operator is not "a compact form of if / else", but an expression that has to produce a result of a specific type, since its use usual is in assignments.

The result of the ternary operator is typically assigned to a variable, so the compiler must be able to check if the type of the result matches the type of the variable. You can not do this check if each "branch" of the ternary operator produces a different type as a result.

In your case, you could have a function, for example ImprimirError() that returns void to use it in the second part of the ternary operator.

But since in your case you are not assigning the result to any place, why use the ternary operator? Simply change it to an if / else. It will also gain in readability.

    
answered by 15.04.2018 в 10:18
5
  

The compiler (Visual Studio 2017) does not recognize me

And he does well not to recognize it, because he is following the instructions of C ++ standard in section §8.16 (my translation):

  

8.16 Conditional Operator

     
  • [...]
  •   
  • If the first or second operand has type void , one of the following conditions must be met:      
  • The second or third operand (but not both) is a expression-throw (possibly in parentheses); the result is of the type and category of the other. The expression-conditional is a bit field if that operand is a bit field.
  •   
  • Both the second and the third operand are of type void , the result is type void and is a pure value of the right side [...].
  •      

    Since none of the conditions to accept that any of the operands is of type void , the program fails. But it's easy to solve:

    (comprar >= 1 && comprar <= 40) ?
        ActualizarAsientos(Asientos, comprar) :
        (void)(cout << "Asiento fuera de rango");
    //  ~~~~~~ <-- conversión a void
    

    If both expressions are of type void , then §8.16.2.2 is met and compiled correctly. But it's not a good idea, follow the advice of abulafia and change the code by if - else :

    if (comprar >= 1 && comprar <= 40)
        ActualizarAsientos(Asientos, comprar);
    else
        cout << "Asiento fuera de rango";
    

    Or make it comply with §8.16.2.1 and capture the exception somewhere:

    (comprar >= 1 && comprar <= 40) ?
        ActualizarAsientos(Asientos, comprar) :
        (throw std::logic_error{"Asiento fuera de rango"});
    
        
    answered by 16.04.2018 в 10:15
    0

    Well a basic solution is to put the message into a void method, since these conditionals are used to return a value;

    variable=condicion?valorSiEsTrue:valorSiEsFalse;
    
        
    answered by 15.04.2018 в 02:52