Стандарт гласит (черновик N3690; это пост C ++ 11, до C ++ 14):
[res.on.functions]
1 В некоторых случаях (функции замены, функции обработчика,
операции над типами, используемыми для создания экземпляра стандартного шаблона библиотеки
компоненты), стандартная библиотека C ++ зависит от компонентов, предоставляемых
программа на C ++. Если эти компоненты не соответствуют их требованиям,
Стандарт не предъявляет никаких требований к реализации .
2 В частности, эффекты не определены в следующих случаях:
- если неполный тип (3.9) используется в качестве аргумента шаблона, когда
создание экземпляра шаблона, если специально не разрешено
этот компонент.
Учитывая, что стандарт не предъявляет никаких требований, а эффекты не определены (насколько я могу судить, это то же самое, что и неопределенное поведение), инстанцирование не ожидает "не сработает" больше, чем ожидание для него (похоже) на «работу».
Начиная с C ++ 17, требование было смягчено, и std::vector
требует , а не требует, чтобы тип значения был завершен, если используется с соответствующим распределителем (соответствующий распределитель по умолчанию). (Эта свобода не распространяется на использование всех функций-членов; у них есть дополнительные требования).
Стандартная цитата (текущий проект):
[vector.overview]
Неполный тип T может использоваться при создании экземпляра вектора, если распределитель удовлетворяет требованиям полноты распределителя.
T должен быть завершен до того, как будет получен какой-либо член результирующей специализации вектора.
[allocator.requirements.completeness]
Если X является классом-распределителем для типа T, X дополнительно отвечает требованиям полноты распределителя, если, является ли T полным типом:
- X - полный тип, а
- все типы членов allocator_traits, кроме value_type, являются полными типами.
[default.allocator]
Все специализации распределителя по умолчанию соответствуют требованиям полноты распределителя ([allocator.requirements.completeness]).