如何声明同一个类的成员向量?

时间:2017-01-28 18:55:23

标签: c++ templates vector member incomplete-type

为什么以下代码有效?

struct A {
    std::vector<A> subAs;
};

A是不完整的类型,对吗?如果有一个A * s的矢量我会理解。但在这里我不明白它是如何工作的。这似乎是一个递归的定义。

1 个答案:

答案 0 :(得分:36)

这个paper被采用into C++17,允许在某些STL容器中使用不完整的类型。在此之前,它是未定义的行为。引用文章:

  

根据对Issaquah会议的讨论,我们实现了   达成共识*采用这种方法 - “不完整的容器   类型“,但将范围限制为std::vectorstd::list和   std::forward_list,作为第一步。

至于标准的变化(强调我的):

  

如果实例化T,则可以使用不完整类型vector    allocator 满足 allocator-completeness-requirements   (17.6.3.5.1)。 T 应在结果的任何成员之前完成   引用了vector的特化。

所以,如果您在实例化std::allocator<T>时保留默认std::vector<T, Allocator>,那么根据论文,它将始终使用不完整类型T;否则,这取决于您的分配器是否可以使用不完整类型T进行实例化。

  

A是不完整的类型,对吗?如果有一个A * s的矢量我会理解。但在这里我不明白它是如何工作的。这似乎是一个递归的定义。

那里没有递归。以极其简化的形式,它类似于:

class A{
    A* subAs;
};

从技术上讲,除了sizecapacity和可能allocator之外,std::vector只需要保存指向它管理的A动态数组的指针它的分配器。 (并且在编译时已知指针的大小。)

因此,实现可能如下所示:

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;
    };

}