Можно ли создать экземпляры стандартных контейнеров с неполными типами?

Иногда полезно создать экземпляр стандартного контейнера с неполным типом для получения рекурсивной структуры:

struct multi_tree_node { // Does work in most implementations
    std::vector< multi_tree_node > child;
};

struct trie_node { // Does not work in most implementations
    std::map< char, trie_node > next;
};

Это обычно работает, потому что контейнеры не имеют членов типа value_type или функций-членов, которые передать или вернуть любые объекты value_type по значению. В Стандарте, кажется, не очень много говорится о неполных аргументах шаблона, но есть один бит в C ++ 11 §17.6.4.8 [lib.res.on.functions], «требования к другим функциям»:

В в частности, эффекты не определены в следующих случаях:… если неполный тип (3.9) используется в качестве аргумента шаблона при создании экземпляра компонента шаблона, если это специально не разрешено для этого компонента.

Делает ли это вышеупомянутые конструкции незаконными, даже если экземпляры не находятся в области видимости блока? Подпадает ли это под «операции над типами, используемыми для создания экземпляров компонентов шаблонов стандартной библиотеки» (также 17.6.4.8)? Или реализации библиотеки запрещено создавать экземпляры шаблонов, которые могут завершиться неудачно для неполных типов, когда все специально требуемые экземпляры завершаются успешно?

Изменить: Поскольку только функции могут вызывать и создавать экземпляры других функций, ограничивая «операции над типами…» теми в области видимости блока, казалось бы, содержит более строгие требования к содержимому функций-членов, чем содержимое сигнатур и определений классов-членов. В конце концов, определенно не имеет смысла делать что-либо с multi_tree_node , пока тип не будет завершен. И это распространяется на std :: unique_ptr , который явно поддерживает аргумент неполного типа даже при использовании в области видимости блока .

Правка 2: Право, что я не утруждал себя тестированием примера trie_node - и я даже пробовал его раньше. Это то же самое, что и пример поломки в статье , на которую ссылается @Ise. Однако, хотя в статье кажется само собой разумеющимся, что «ничего подобного не может работать», решение кажется мне простым - внутренний класс tree_node std :: map должен быть шаблон, не являющийся членом, а не класс, не являющийся членом.

Как бы то ни было, эта статья довольно хорошо описывает замысел дизайна, так что я полагаю, что моя придирка к подзаголовку «требования к функциям» - всего лишь это.

16
задан Potatoswatter 30 November 2011 в 20:32
поделиться