¿Cómo puedo declarar un vector miembro de la misma clase?
¿Por qué diablos funciona el siguiente código?
struct A {
std::vector<A> subAs;
};
A es un tipo incompleto, ¿verdad? Si hubiera un vector de A*s lo entendería. Pero aquí no entiendo cómo funciona. Parece ser una definición recursiva.
1 answers
Este documento fue adoptado en C++17 que permite utilizar tipos incompletos en ciertos contenedores STL. Antes de eso, era un Comportamiento Indefinido. Para citar del documento:
Basado en la discusión sobre la reunión de Issaquah, logramos el consenso para proceder* con el enfoque - " Contenedores de Incompletos Types", pero limita el alcance a
std::vector
,std::list
, ystd::forward_list
, como primer paso.
Y en cuanto a los cambios en la norma (énfasis mío):
Se puede utilizar un tipo incompleto
T
al instanciarvector
si el el asignador cumple los requisitos de integridad del asignador (17.6.3.5.1). T se completará antes que cualquier miembro de la resultante se hace referencia a la especialización del vector.
Así que, ahí lo tienes, si dejas el predeterminado std::allocator<T>
en su lugar al instanciar el std::vector<T, Allocator>
, entonces siempre funcionará con un tipo incompleto T
de acuerdo de lo contrario, depende de que su Asignador sea instanciable con un tipo incompleto T
.
A es un tipo incompleto, ¿verdad? Si hubiera un vector de A*s lo entendería. Pero aquí no entiendo cómo funciona. Parece ser una definición recursiva.
No hay recursión allí. En una forma extremadamente simplificada, es similar a:
class A{
A* subAs;
};
Técnicamente, aparte de size
, capacity
y, posiblemente,allocator
, std::vector
sólo necesita mantener un puntero a una matriz dinámica de A
que administra a través de su asignador. (Y el tamaño de un puntero se conoce en tiempo de compilación.)
Entonces, una implementación puede verse así:
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;
};
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-21 11:30:13