Скобка в инициализации std :: array
Предположим, что естьсstd::array
быть инициализированным. Это'Хорошо, если вы используете двойные скобки:
std::array x = {{0, 1}};
std::array x{{0, 1}};
Это'Также можно использовать одиночные скобки в старой доброй инициализации агрегата, так как исключение скобок позаботится об отсутствующих скобках:
std::array x = {0, 1};
Однако можно ли использовать инициализацию списка с одинарными скобками? GCC принимает это, Clang отклоняет это с "не может опустить скобки вокруг инициализации подобъекта при использовании прямой инициализации списка ".
std::array x{0, 1};
Единственная часть стандарта, в которой упоминается исключение скобок, - это 8.5.1 / 12, которая гласит:
Все неявные преобразования типов (раздел 4) учитываются при инициализации агрегатного члена с помощью выражения присваивания. Если выражение присваивания может инициализировать элемент, элемент инициализируется. В противном случае, если элемент сам является субагрегатом, предполагается скобка elision, а выражение присваивания рассматривается для инициализации первого члена субагрегата.
8.5.1 именно об агрегированной инициализации, так что это должно означать, что Clang правильно отклонить, верно? Не так быстро. 8.5.4 / 3 говорит:
Инициализация списка объекта или ссылки типа T определяется следующим образом: […] -
В противном случае, если T является агрегатом, выполняется агрегатная инициализация (8.5.1).
Я думаю, что это означает, что применяются те же самые правила, что и для общей инициализации, включая удаление скобок, что означает, что GCC является правильным для принятия.
Признаюсь, формулировка не особо понятна. Итак, какой компилятор прав в обработке третьего фрагмента? Происходит ли удаление скобок при инициализации списка, или нетт?