Иногда бывает полезно создать экземпляр стандартного контейнера с неполным типом для получения рекурсивной структуры:
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
, который явно поддерживает аргумент неполного типа, , даже когда используется в области видимости блока .
Edit 2: Служит мне право не беспокоитьпроверить пример trie_node
- и я даже пробовал это раньше.Это так же, как пример поломки в статье , на которую ссылается @Ise.Однако, хотя статья, как представляется, считает само собой разумеющимся, что «ничего подобного не может работать», решение кажется мне простым - внутренний tree_node
класс std::map
должен быть шаблоном, не являющимся членом, а не элементом, не являющимся членом.class.
В любом случае, эта статья довольно хорошо определяет замысел дизайна, поэтому я предполагаю, что моя придирка к тому, что я попал в подзаголовок «требований к функциям», это всего лишь то, что