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

后端 未结 2 1331
时光取名叫无心
时光取名叫无心 2020-12-09 08:21

My compiler is the latest VC++ 2013 RC.

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


        
相关标签:
2条回答
  • 2020-12-09 08:43

    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.

    0 讨论(0)
  • 2020-12-09 08:48

    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.

    0 讨论(0)
提交回复
热议问题