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