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

Posted

技术标签:

【中文标题】类(或结构)通过模板自引用【英文标题】:class (or struct) self-reference by template 【发布时间】:2015-12-05 21:30:40 【问题描述】:

以下合法吗?

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

对this post 的评论似乎表明它不是。


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

In my tests 这似乎工作正常(我使用了 GCC 和 Clang -- 都使用了 -Wall -Werror -std=c++11)。

语言定义(C++17 之前)中是否有某些内容直接或间接地将其指定为未定义的行为,还是只是未指定


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

typedef int T;
struct tree_node;

struct tree_node
   
   T t;
   tree_node * children;
   

【问题讨论】:

可能重复:***.com/questions/31345193/… “shared_ptr 的例外”让我大吃一惊:***.com/a/31347287/86967 最坏的情况,你可以使用shared_ptr&lt;tree_node&gt; 而不是tree_node ...或者shared_ptr&lt;vector&lt;tree_node&gt;&gt; 【参考方案1】:

实际上,由于 N4371 我们有(来自 N4527,[vector.overview],将在 C++17 中):

如果分配器满足分配器完整性,则在实例化向量时可以使用不完整类型T 要求 17.6.3.5.1。 T 应在由此产生的专业化的任何成员之前完成 向量被引用。

在此之前,vector 不能用不完整的类型(tree_node 在那个时候)构造,这将是未定义的行为。

【讨论】:

这太不可思议了。这么松的需求怎么做小对象优化? @v.oddou std::vector 不会做小的缓冲区优化。 这不是我们可以确定的,“std::vector 的这个实现”确实没有做到这一点。但未指定实现。如果我们开始在规范中加入这些奇怪的措辞,那么现在的实现就会被限制为不这样做,而是由于错误而不是明确的设计。 @v.oddou 当然可以。 std::vector 必须支持不完整的类型,swap 不能使迭代器无效。 是的,但这就是我的意思。标准中没有明确说“禁止小对象优化”。它是由不相关的短语设置的约束所暗示的。这似乎是一个错误。

以上是关于类(或结构)通过模板自引用的主要内容,如果未能解决你的问题,请参考以下文章

通过引用或值捕获句柄到类模板ctor

成员引用基类型“类”不是结构或联合——Fixit 是不是将我引向了正确的方向?

java回调方法钩子方法以及模板方法模式

包含对其自身实例的引用的标准向量的模板类

可空引用类型:如何指定“T?”类型不限于类或结构

创建具有自引用类型提示的递归数据类