Sử dụng C++, tôi đang cố gắng tạo một lớp chứa chung để xử lý nhiều kiểu dữ liệu. Đó là một vấn đề phổ biến với nhiều giải pháp khác nhau, nhưng tôi không tìm thấy gì ... trực quan như tôi đã quen với các ngôn ngữ như Python hoặc thậm chí VB/VBA ...Vùng chứa chung cho nhiều kiểu dữ liệu trong C++
Vì vậy, đây là kịch bản của tôi:
Tôi đã xây dựng một lớp DataContainer dựa trên boost :: bất kỳ thứ gì tôi sử dụng để lưu trữ nhiều loại dữ liệu của nhiều phần tử. Tôi sử dụng một bản đồ như tuyên bố:
std::map<std::string, DataContainer* (or DataContainerBase*)>
nơi DataContainer là một lớp mà đóng gói một đối tượng của loại:
std::list<boost::any>
cùng với các chức năng thuận tiện cho việc quản lý/truy cập vào danh sách.
Tuy nhiên, cuối cùng, tôi vẫn buộc phải thực hiện chuyển đổi loại bên ngoài vùng chứa dữ liệu.
Ví dụ, nếu tôi được lưu trữ một danh sách các int giá trị trong bản đồ, truy cập vào chúng sẽ yêu cầu:
int value = boost::any_cast<int>(map["myValue"]->get());
Tôi thà mã tăng được chứa hoàn toàn trong cấu trúc chứa dữ liệu, do tôi sẽ chỉ cần loại:
int value = map["myValue"]->get();
hoặc, trường hợp xấu nhất:
int value = map["myValue"]->get<int>();
Tất nhiên, tôi đồng ULD liệt kê các kiểu dữ liệu của tôi và làm điều gì đó như:
int value = map["myValue"]->get(TYPE_INT);
hoặc viết loại cụ thể get() chức năng:
getInt(), getString(), getBool() ...
Vấn đề với hai lựa chọn cuối cùng là họ có phần cứng nhắc, đòi hỏi tôi để khai báo rõ ràng từng loại tôi muốn lưu trữ trong vùng chứa. Các giải pháp any_cast (mà tôi đã thực hiện và hoạt động) Tôi giả sử là tốt, nó chỉ là ... inelegant? Tôi không biết. Có vẻ như tôi cũng không nên sử dụng cơ chế bên trong nữa.
Như tôi thấy, chuyển giá trị mà không khai báo loại giá trị trong cuộc gọi đến hàm thành viên DataContainer sẽ yêu cầu giải pháp void * (không mong muốn vì lý do rõ ràng) và sử dụng cuộc gọi "get()" yêu cầu (cho đến nay như tôi có thể nói) một chức năng thành viên "mẫu ảo" được định nghĩa ở cấp độ cơ sở, trong đó, tất nhiên, không được phép.
Vì vậy, tôi có giải pháp khả thi và thực sự, việc sử dụng của tôi trong trường hợp này bị giới hạn trong phạm vi mà hầu hết mọi giải pháp đều hoạt động tốt. Nhưng tôi tự hỏi nếu có lẽ có một cách linh hoạt hơn để quản lý một thùng chứa dữ liệu chung, nhiều loại hơn thế này.
Có một cái nhìn về 'boost :: variant' quá, có lẽ đây là những gì bạn đang tìm kiếm (?). – Kos
Có gì sai với chỉ 'std :: map'? –
Ngoài ra, vì 'DataContainer' của bạn nằm dưới sự kiểm soát của bạn, tại sao không chỉ thêm một hàm thành viên' template get_as() {return boost :: any_cast (get()); } 'để bọc bất kỳ diễn viên? Sau đó, bạn có thể nói 'm [" abc "] -> get_as ()', như bạn đã đề xuất. Âm thanh đủ đơn giản. –