Подтвердить что ты не робот

Почему в trernary operator не может использоваться список braced-init-list?

Мой компилятор - это последний VС++ 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 : '{'
}

Почему в ternary-операторе оператор braced-init-list не может быть использован?

Является ли это поведение определенным как плохо сформированный стандартом С++ или просто ошибка компилятора VС++?

4b9b3361

Ответ 1

Ну, вот что говорится в стандартном списке (8.5.3.1):

Список инициализация можно использовать

  • как инициализатор в определении переменной (8.5)
  • как инициализатор в новом выражении (5.3.4)
  • в операторе return (6.6.3)
  • как аргумент функции (5.2.2)
  • как индекс (5.2.1)
  • в качестве аргумента для вызова конструктора (8.5, 5.2.3)
  • как инициализатор для нестатического элемента данных (9.2)
  • в mem-initializer (12.6.2)
  • в правой части присваивания (5.17)

Так как это не упоминает условный оператор, я думаю, ваш компилятор прав. Также обратите внимание, что условный оператор ожидает выражения с обеих сторон от : (5.16), и, насколько я понимаю, инициализатор скобок не является выражением.

Ответ 2

Это синтаксическая ошибка. Список braced-init-list не является выражением, и он не имеет типа или значения. Список braced-init-list доступен в разных местах в грамматике С++, а операнды условного выражения не являются одним из этих мест. Поэтому ваш код не может даже разобрать.

Если вы хотите сделать это:

struct T { ... };

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

вместо этого вы можете сделать это:

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

и я верю, хотя для этого требуется конструктор перемещения, он не будет использовать его, и RVO будет входить.

В качестве альтернативы вы могли бы, конечно, сделать следующее:

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

чтобы получить все преимущества инициализации списка.