問題描述
到底為什么下面這段代碼有效?
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.
推薦答案
這個 paper 被引入 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):
一個不完整的類型 T
可以在實例化 vector
時使用,如果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
時保留默認的 std::allocator
,那么根據論文,它將始終使用不完整的類型 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;
};
}
這篇關于如何聲明同一類的成員向量?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!