Ответ 1
От n4140
§ 9.2.2 [class.mem] (Акцент)
Класс считается полностью определенным типом объекта (3.9) (или полный тип) при закрытии
}
спецификатора класса. В рамках класса, класс считается полным в пределах функциональные тела, аргументы по умолчанию, использование-объявления, представляющие наследующие конструкторы (12.9), спецификации исключений и скопированные или равные инициализаторы для нестатических членов данных (в том числе такие вещи во вложенных классах). В противном случае он считается неполным в пределах своей спецификации класса.
Clang и GCC верны. Класс не считается завершенным, когда вы объявляете своего члена static constexpr
, поэтому вы не можете его построить. Вот почему перенос определения Bar
out или удаление static constexpr
работает (потому что он считается полным при определении нестатических элементов)
Чтобы прояснить, особенно учитывая этот вопрос: Статический член constexpr внутреннего класса
Стандартизированный I, приведенный выше, в основном означает, что если не указано иное, класс считается неполным внутри себя *. Инициализатор static
, constexpr
или static constexpr
не подпадает под указанную иначе часть, и поэтому мы не можем использовать объявленную в классе что-либо, которая включает вложенный тип класса.
* означает, что вы не можете использовать его или его членов в объявлении класса. Наиболее известным исключением является функция-член.