std::deque<S> *p; // seems to be UB like the previous case,
// but is it ok if p is not used till S is defined?
Это на самом деле интересный бит здесь. Да, создание экземпляра этого контейнера с неполным типом не допускается, это не предусмотрено. Но возникает вопрос, действительно ли он создан. Согласно основному языку, это не обязательно.
[temp.inst]
1, если специализация шаблона класса не была явно создана или специализирована , специализация шаблона класса создается неявно, когда на специализацию ссылаются в контексте, требующем полностью определенного типа объекта, или когда полнота типа класса влияет на семантику программы.
Указатель на тип не требует, чтобы тип был полным. Таким образом, одного этого объявления обычно недостаточно для создания экземпляра шаблона класса, и поэтому может быть преждевременно определять, что требование контейнера здесь нарушено.
Если, конечно, мы не возьмем полнота типа класса влияет на семантику программы для включения нарушений контракта в стандартную библиотеку. Я полагаю, реализация может создать здесь экземпляр. Однако я не знаю ни о какой реализации, поэтому это может быть не интерпретация желаний.
Так что, чтобы ошибиться в сторону осторожности, я бы тоже подумал об этом UB.
std::deque<S*> p; // not really sure about this one
Это хорошо. Независимо от того, является ли S
полным, S*
по-прежнему является полным типом объекта. Я говорю это, потому что это не включено в
[основные.типы]
5 Класс, который был объявлен, но не определен, перечисление type в определенных контекстах ([dcl.enum]) или массив неизвестного связанного или неполного типа элемента является не полностью определенным типом объекта. Неполностью определенные типы объектов и cv void являются неполными типами ([basic.fundamental]). Объекты не должны иметь неполный тип.
Ограничения на полноту S
появляются только при попытке использовать такой указатель в выражениях, выполняющих разыменование или арифметику указателя. Но сам тип указателя все еще завершен. Так что это допустимый аргумент шаблона для типа контейнера.
person
StoryTeller - Unslander Monica
schedule
23.07.2020
std::list<S*> p;
в порядке. Компилятору не должно быть проблемой генерировать указатель на структуру без ее макета/размера. ? - person Tony Tannous   schedule 23.07.2020list
, потому что думал, что у него нет разрешения на использование неполных типов. Но ответ эорики предполагает, что это так. Тогда мне придется отредактировать вопрос. - person cigien   schedule 23.07.2020