La norma requiere que sea capaz de crear una matriz de un tipo de estructura. Cuando lo hace, se requiere que la matriz sea contigua. Eso significa que, independientemente del tamaño asignado para la estructura, tiene que ser uno que le permita crear una matriz de ellos. Para asegurarse de que, el compilador puede asignar espacio adicional dentro de la estructura, pero no puede requerir espacio adicional entre las estructuras.
El espacio para los datos en un vector
es (normalmente) asignado con ::operator new
(a través de una clase de Allocator), y ::operator new
se requiere para asignar espacio que está correctamente alineado para almacenar cualquier tipo.
Puede suministrar su propio Asignador y/o sobrecargar ::operator new
- pero si lo hace, su versión todavía debe cumplir con los mismos requisitos, por lo que no cambiará nada a este respecto.
En otras palabras, exactamente lo que quiere que se requiere para trabajar, siempre y cuando los datos en el archivo fue creado esencialmente de la misma forma en que está tratando de leerlo de nuevo. Si se creó en otra máquina o con un compilador diferente (o incluso el mismo compilador con diferentes indicadores) tiene una cantidad considerable de problemas potenciales: puede obtener diferencias en endianness, relleno en la estructura, etc.
Editar: Dado que usted no sabe si las estructuras se han escrito en el formato esperado por el compilador, que no sólo es necesario leer las estructuras uno a la vez - que realmente necesita para leer el los elementos en las estructuras uno a la vez, luego coloque cada uno en un struct
temporal, y finalmente agregue el struct
rellenado a su colección.
Afortunadamente, puede sobrecargar operator>>
para automatizar la mayor parte de esto. No mejora la velocidad (por ejemplo), pero puede mantener su código más limpio:
struct whatever {
int x, y, z;
char stuff[672-3*sizeof(int)];
friend std::istream &operator>>(std::istream &is, whatever &w) {
is >> w.x >> w.y >> w.z;
return is.read(w.stuff, sizeof(w.stuff);
}
};
int main(int argc, char **argv) {
std::vector<whatever> data;
assert(argc>1);
std::ifstream infile(argv[1]);
std::copy(std::istream_iterator<whatever>(infile),
std::istream_iterator<whatever>(),
std::back_inserter(data));
return 0;
}
¿Están esas estructuras escritas en el archivo por código heredado o lo controlas también? –
Están escritos por código heredado. Incluso si pudiera cambiarlo, podría tener que leer archivos escritos por versiones anteriores de la aplicación. – Nate