如何声明相同类的成员向量? [英] How can I declare a member vector of the same class?
问题描述
到底为什么下面的代码起作用?
Why on earth does the following piece of code work?
struct A {
std::vector<A> subAs;
};
A是不完整的类型,对吗?如果有一个A * s的向量,我会理解的.但是在这里我不明白它是如何工作的.这似乎是一个递归定义.
A is an incomplete type, right? If there was a vector of A*s I would understand. But here I don't understand how it works. It seems to be a recursive definition.
推荐答案
此纸张被导入C ++ 17 ,它允许在某些STL容器中使用不完整的类型.在此之前,它是未定义的行为.引用本文:
This paper was adopted into C++17 which allows incomplete types to be used in certain STL containers. Prior to that, it was Undefined Behavior. To quote from the paper:
基于Issaquah会议的讨论,我们实现了 共识*,以继续采用该方法–不完整的容器 类型",但将范围限制为
std::vector
,std::list
和std::forward_list
,作为第一步.
Based on the discussion on the Issaquah meeting, we achieved the consensus to proceed* with the approach – "Containers of Incomplete Types", but limit the scope to
std::vector
,std::list
, andstd::forward_list
, as the first step.
关于标准的变化(重点是我的):
And as for the changes in the standard (emphasis mine):
如果实例化
vector
,则可能会使用不完整的类型T
. allocator 满足 allocator-completeness-requirements (17.6.3.5.1). T 必须在结果的任何成员之前完成 向量的专业化.
An incomplete type
T
may be used when instantiatingvector
if the allocator satisfies the allocator-completeness-requirements (17.6.3.5.1). T shall be complete before any member of the resulting specialization of vector is referenced.
因此,如果在实例化std::vector<T, Allocator>
时将默认的std::allocator<T>
保留在原位,则该文件将始终使用不完整的类型T
起作用.否则,这取决于您的 Allocator 是否可以使用不完整的类型T
实例化.
So, there you have it, if you leave the default std::allocator<T>
in place when instantiating the std::vector<T, Allocator>
, then it will always work with an incomplete type T
according to the paper; otherwise, it depends on your Allocator being instantiable with an incomplete type T
.
A是不完整的类型,对吗?如果有一个A * s的向量,我会理解的.但是在这里我不明白它是如何工作的.这似乎是一个递归定义.
A is an incomplete type, right? If there was a vector of A*s I would understand. But here I don't understand how it works. It seems to be a recursive definition.
那里没有递归.以极其简化的形式,它类似于:
There is no recursion there. In an extremely simplified form, it's similar to:
class A{
A* subAs;
};
从技术上讲,除了size
,capacity
以及可能的allocator
外,std::vector
仅需要保留指向通过分配器管理的A
动态数组的指针. (并且在编译时就知道了指针的大小.)
Technically, apart from size
, capacity
and possibly allocator
, std::vector
only needs to hold a pointer to a dynamic array of A
it manages via its allocator. (And the size of a pointer is known at compile time.)
因此,一个实现可能看起来像这样:
So, an implementation may look like this:
namespace std{
template<typename T, typename Allocator = std::allocator<T>>
class vector{
....
std::size_t m_capacity;
std::size_t m_size;
Allocator m_allocator;
T* m_data;
};
}
这篇关于如何声明相同类的成员向量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!