Это зависит от точного правила. Нарушения большинства правил, связанных с неполными типами классов в разделе основного языка стандарта, должны быть диагностированы. Использование в качестве аргумента шаблона для шаблона стандартной библиотеки является неопределенным поведением, если не указано иное, что дает немного больше возможностей для реализаций.
Эти правила требуют диагностики (так как они указаны с помощью «должны»):
[basi c .def] / 5 :
В определении объекта тип этого объекта не должен быть неполным типом ([basi c .types]), абстрактный тип класса или его (возможно многомерный) массив.
[dcl.fct.def.general] / 2 :
Тип параметра или возвращаемого типа для определения функции не должен быть (возможно, квалифицированным по cv) типом класса, который является неполным или абстрактным в теле функции, если функция не удалена ( [dcl.fct.def.delete]).
[expr.ref] / 4 (относительно типа выражения операнда перед оператором .
):
Тип класса должен быть завершен, если не появится доступ к члену класса s в определении этого класса. [ Примечание: Если класс неполный, поиск в полном типе класса необходим для ссылки на то же объявление ([basi c .scope.class]). - конечная нота ]
Поскольку встроенное значение оператора ->
определяется с A->B
, эквивалентным (*A).B
, это также относится к ->
операторные выражения.
[class.mem] / 15 :
Тип элемента данных non-stati c не должен быть неполным ([basi c .types]), абстрактный тип класса ([class.abstract]) или его (возможно, многомерный) массив. [ Примечание: В частности, класс C не может содержать нестати c член класса C, но он может содержать указатель или ссылку на объект класса C. - конечная нота ]
[class.derived] / 2 (относительно списка базовых классов для определения класса):
A class-or-decltype должен обозначать (возможно, cv-квалифицированный) тип класса, который не является не полностью определенным классом ([class.mem]); любые cv-квалификаторы игнорируются.
Существуют и другие основные языковые правила, запрещающие неполные типы классов, но наиболее распространенными являются приведенные выше. См. Также ненормативный список контекстов, требующих полного класса в [basi c .def.odr] / 12 .
Я не вижу прямого правила, что qualid-id scope::name
неверно сформирован, если scope
назовет неполный тип класса, но может просто случиться так, что поиск имени в этом случае обязательно завершится, что является диагностируемым нарушением.
Для Стандартной библиотеки общий запрет на неполные типы в качестве аргументов шаблона составляет [res.on.functions] / (2.5) :
В некоторых случаях (замена функции, функции-обработчики, операции над типами, используемыми для создания экземпляров стандартных шаблонов библиотеки), стандартная библиотека C ++ зависит от компонентов, предоставляемых программой C ++. Если эти компоненты не соответствуют их требованиям, этот документ не предъявляет требований к реализации.
В частности, эффекты не определены в следующих случаях:
Как уже отмечалось, в C ++ 17 добавлено конкретное c разрешение на создание экземпляра класса std::vector<T, Alloc>
, но ни один из его членов, если T
не является полным и Alloc
удовлетворяет «требованиям полноты распределителя» ( [vector.overview] / 4 )