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

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.

推荐答案

这个 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::vectorstd::liststd::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, and std::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 instantiating vector 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;
};

技术上,除了sizecapacity和可能的allocatorstd::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;
    };

}

这篇关于如何声明同一类的成员向量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

本站部分内容来源互联网,如果有图片或者内容侵犯了您的权益,请联系我们,我们会在确认后第一时间进行删除!

相关文档推荐

How do compilers treat variable length arrays(编译器如何处理变长数组)
Deduce template argument from std::function call signature(从 std::function 调用签名推导出模板参数)
check if member exists using enable_if(使用 enable_if 检查成员是否存在)
Standard Library Containers with additional optional template parameters?(具有附加可选模板参数的标准库容器?)
Uses of a C++ Arithmetic Promotion Header(C++ 算术提升标头的使用)
Parameter pack must be at the end of the parameter list... When and why?(参数包必须位于参数列表的末尾...何时以及为什么?)