46 votes

Comment puis-je déclarer un membre de vecteur de la même classe?

Pourquoi sur la terre ne le morceau suivant du code du travail?

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

Un est un type incomplète, non? Si il y avait un vecteur de A*s je voudrais comprendre. Mais ici, je ne comprends pas comment il fonctionne. Il semble être une définition récursive.

37voto

WhiZTiM Points 3351

Ce document a été adopté en C++17 qui permet incomplète types à utiliser dans certains conteneurs STL. Avant cela, il a un Comportement Indéfini. Pour citer le document:

Sur la base des débats sur la Issaquah réunion, nous avons atteint l' le consensus de procéder* avec l'approche des "Conteneurs de la Incomplètes Types", mais de limiter la portée d' std::vector, std::list, et std::forward_list, que la première étape.

Et comme pour les changements dans la norme (l'emphase est mienne):

Un type incomplète T peut être utilisé lors de l'instanciation vector si l' allocateur satisfait à l' allocateur-exhaustivité-exigences (17.6.3.5.1). T doit être terminé avant que tout membre de la la spécialisation de vecteur est référencé.

Donc, là vous l'avez, si vous laissez la valeur par défaut std::allocator<T> en place lors de l'instanciation de l' std::vector<T, Allocator>, alors il sera toujours travailler avec un type incomplète T selon l'étude; sinon, cela dépend de votre Allocation d'être instanciable avec un type incomplète T.


Un est un type incomplète, non? Si il y avait un vecteur de A*s je voudrais comprendre. Mais ici, je ne comprends pas comment il fonctionne. Il semble être une définition récursive.

Il n'y a pas de récursivité. En très simplifié, il est semblable à:

class A{
    A* subAs;
};

Techniquement, hormis size, capacity et, éventuellement, allocator, std::vector seulement besoin d'un pointeur vers un tableau dynamique d' A il gère par l'intermédiaire de son allocation. (Et de la taille d'un pointeur est connu au moment de la compilation.)

Ainsi, une application peut ressembler à ceci:

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

}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X