Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can braced-init-list not be used in ternary operator?

My compiler is the latest VC++ 2013 RC.

int f(bool b) {     return {}; // OK     return b ?  1  : { }; // C2059: syntax error : '{'     return b ?  1  : {0}; // C2059: syntax error : '{'     return b ? {1} : {0}; // C2059: syntax error : '{' } 

Why can braced-init-list not be used in ternary operator?

Is this behavior defined as ill-formed by the C++ standard, or just a bug of the VC++ compiler?

like image 962
xmllmx Avatar asked Sep 17 '13 06:09

xmllmx


People also ask

What is a braced init list?

AFAIK a braced-init-list is a uniform way to initialize an object.

How do you handle 3 conditions in a ternary operator?

The conditional (ternary) operator is the only JavaScript operator that takes three operands: a condition followed by a question mark ( ? ), then an expression to execute if the condition is truthy followed by a colon ( : ), and finally the expression to execute if the condition is falsy.

Which operator is used as ternary operator?

Remarks. The conditional operator (? :) is a ternary operator (it takes three operands). The conditional operator works as follows: The first operand is implicitly converted to bool .

Which is better if-else or ternary operator?

If the condition is short and the true/false parts are short then a ternary operator is fine, but anything longer tends to be better in an if/else statement (in my opinion).


2 Answers

Well, here's what the standard says about the braced-init-list (8.5.3.1):

List-initialization can be used

  • as the initializer in a variable definition (8.5)
  • as the initializer in a new expression (5.3.4)
  • in a return statement (6.6.3)
  • as a function argument (5.2.2)
  • as a subscript (5.2.1)
  • as an argument to a constructor invocation (8.5, 5.2.3)
  • as an initializer for a non-static data member (9.2)
  • in a mem-initializer (12.6.2)
  • on the right-hand side of an assignment (5.17)

Since this doesn't mention the conditional operator, I guess your compiler is right. Also note that the conditional operator expects expressions on the both sides of : (5.16), and as far as I understand, a brace-initializer is not an expression.

like image 105
SingerOfTheFall Avatar answered Oct 07 '22 16:10

SingerOfTheFall


It's a syntax error. A braced-init-list is not an expression, and it doesn't have a type or value category. braced-init-list is available at various locations in the C++ grammar, and the operands of conditional expression are not one of those locations. Therefore your code fails to even parse.

If you want to do this:

struct T { ... };  T f(bool b) {     return b ? {i,j,k} : {x,y}; } 

instead you could do this:

T f(bool b) {     return b ? T{i,j,k} : T{x,y}; } 

and I believe, although this requires a move constructor, it wouldn't use it and RVO would kick in.

Alternatively you could of course do this:

T f(bool b) {     if (b)         return {i,j,k};     else         return {x,y}; } 

to get all the advantages of list-initialization.

like image 45
Andrew Tomazos Avatar answered Oct 07 '22 18:10

Andrew Tomazos