Tiêu chuẩn yêu cầu bạn có thể tạo một mảng kiểu cấu trúc. Khi bạn làm như vậy, mảng được yêu cầu phải tiếp giáp. Điều đó có nghĩa, bất kỳ kích thước nào được phân bổ cho cấu trúc, nó phải là một cái cho phép bạn tạo một mảng của chúng. Để đảm bảo rằng, trình biên dịch có thể phân bổ thêm không gian bên trong cấu trúc, nhưng không thể yêu cầu thêm bất kỳ khoảng trắng nào giữa các cấu trúc.
Không gian cho dữ liệu trong một vector
là (thường) được phân bổ với ::operator new
(thông qua lớp Allocator) và ::operator new
là bắt buộc để phân bổ không gian phù hợp để lưu trữ bất kỳ loại nào.
Bạn có thể cung cấp Allocator của riêng bạn và/hoặc quá tải ::operator new
- nhưng nếu có, phiên bản của bạn vẫn được yêu cầu để đáp ứng các yêu cầu tương tự, vì vậy nó sẽ không thay đổi bất cứ điều gì về mặt này.
Nói cách khác, chính xác những gì bạn muốn là cần thiết để làm việc miễn là dữ liệu trong tệp được tạo theo cách cơ bản giống như cách bạn đang cố đọc lại. Nếu nó được tạo trên máy khác hoặc với một trình biên dịch khác (hoặc thậm chí là trình biên dịch tương tự với các cờ khác nhau) bạn có một số công bằng các vấn đề tiềm ẩn - bạn có thể nhận được sự khác biệt về tính cuối cùng, đệm trong cấu trúc, v.v.
Chỉnh sửa: Do bạn không biết liệu các cấu trúc đã được viết ra theo định dạng mà trình biên dịch mong đợi, bạn không chỉ cần đọc từng cấu trúc - bạn thực sự cần đọc các mục trong các cấu trúc tại một thời điểm, sau đó đặt từng mục vào một tạm thời struct
và cuối cùng thêm phần đó vào số struct
vào bộ sưu tập của bạn.
May mắn thay, bạn có thể quá tải operator>>
để tự động hóa hầu hết việc này. Nó không cải thiện tốc độ (ví dụ), nhưng nó có thể giữ mã sạch của bạn:
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;
}
Các cấu trúc đó có được viết bằng tệp theo mã cũ hay bạn có kiểm soát được không? –
Chúng được viết bằng mã kế thừa. Ngay cả khi tôi có thể thay đổi nó, tôi có thể phải đọc trong các tập tin được viết bởi các phiên bản cũ của ứng dụng. – Nate