类(或结构体)通过模板进行自引用

13

以下内容是否合法?

template< typename T >
struct tree_node
   {
   T t;
   std::vector<tree_node> children;
   };

针对这篇文章的一条评论似乎表明它不是未定义行为。


编辑:我认为这不是一种“未定义行为”类型的场景。预期的语义是明确无歧义的。如果这是不完整类型的无效使用,则应该是编译时错误。

在我的测试中,这似乎可以正常工作(我同时使用了GCCClang--都带有-Wall -Werror -std=c++11)。

在C++17之前的语言规范中是否有直接或间接地将此指定为未定义行为的内容,或者只是未充分说明?


请注意,这与以下内容在结构上非常相似:

typedef int T;
struct tree_node;

struct tree_node
   {
   T t;
   tree_node * children;
   }

1
可能是重复的问题:https://dev59.com/DV0Z5IYBdhLWcg3whQwj - NathanOliver
“exception for shared_ptr”这个让我笑翻了:https://dev59.com/DV0Z5IYBdhLWcg3whQwj#31347287 - Brent Bradburn
最坏的情况下,您可以使用 shared_ptr<tree_node> 而不仅仅是 tree_node - Brent Bradburn
或者可能是 shared_ptr<vector<tree_node>> - Brent Bradburn
1个回答

14

实际上,由于N4371的结果,我们有了以下内容(来自N4527,[vector.overview],将在C++17中实现):

如果分配器满足分配器完整性要求17.6.3.5.1,则可以在实例化向量时使用不完整类型T。在引用向量的任何成员之前,T必须是完整的。

在此之前,vector不能使用不完整类型(此时tree_node为不完整类型),这将导致未定义行为。


真不错。你是怎么在这样宽松的要求下进行小对象优化的? - v.oddou
@v.oddou std::vector 没有进行小缓冲优化。 - Barry
我们无法确定,“std::vector的这个实现”不会这样做,当然。但是实现没有被指定。如果我们开始在规范中加入这些奇怪的短语,那么实现就会受到限制,不能这样做,但这是由于错误而不是明确的设计。 - v.oddou
@v.oddou 当然可以。std::vector必须支持不完整类型,而且swap不能使迭代器失效。 - Barry
是的,但这就是我的意思。标准中并没有明确规定“禁止小对象优化”。这是从不相关措辞设置的限制中暗示出来的。这似乎是一个错误。 - v.oddou

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接