类(或结构)通过模板自引用
Posted
技术标签:
【中文标题】类(或结构)通过模板自引用【英文标题】:class (or struct) self-reference by template 【发布时间】:2015-09-09 19:20:00 【问题描述】:以下合法吗?
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<tree_node>
而不是tree_node
。
...或者shared_ptr<vector<tree_node>>
。
【参考方案1】:
实际上,由于 N4371 我们有(来自 N4527,[vector.overview],将在 C++17 中):
如果分配器满足分配器完整性,则在实例化向量时可以使用不完整类型
T
要求 17.6.3.5.1。T
应在由此产生的专业化的任何成员之前完成 向量被引用。
在此之前,vector
不能用不完整的类型构造(此时 tree_node
就是这样),这将是未定义的行为。
【讨论】:
这太不可思议了。这么松的需求怎么做小对象优化? @v.oddoustd::vector
不会做小的缓冲区优化。
这不是我们可以确定的事情,“std::vector 的这种实现”确实没有做到这一点。但未指定实现。如果我们开始将这些奇怪的措辞放入规范中,那么现在的实现就会被限制为不这样做,而是由于错误而不是明确的设计。
@v.oddou 当然可以。 std::vector
必须支持不完整的类型,swap
不能使迭代器无效。
是的,但这就是我的意思。标准中没有明确说“禁止小对象优化”。它是由不相关的短语设置的约束所暗示的。这似乎是一个错误。以上是关于类(或结构)通过模板自引用的主要内容,如果未能解决你的问题,请参考以下文章