【问题标题】:class (or struct) self-reference by template类(或结构)通过模板自引用
【发布时间】:2023-04-09 08:28:01
【问题描述】:

以下合法吗?

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

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


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

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

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


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

typedef int T;
struct tree_node;

struct tree_node
   {
   T t;
   tree_node * children;
   }

【问题讨论】:

标签: c++ class language-lawyer self-reference


【解决方案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 不能使迭代器无效。
  • 是的,但这就是我的意思。标准中没有明确说“禁止小对象优化”。它是由不相关的短语设置的约束所暗示的。这似乎是一个错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-07-14
  • 2011-06-20
  • 2011-08-01
  • 2013-01-08
  • 1970-01-01
相关资源
最近更新 更多