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?
AFAIK a braced-init-list is a uniform way to initialize an object.
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.
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 .
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).
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With