2009-03-30 31 views
8

Tôi muốn tạo một thông báo có độ dài hoặc số lượng đối số không xác định. Tôi lấy một mẫu đơn giản nhưCách đặt các loại mẫu khác nhau vào một vector

template <typename T> class Argument { 
public: 
    int size; 
    int type; 
    T data; 
}; 

và với một số quá tải

addMessage (int value) { 
    Argument<int> *a = new Argument<int>; 
    vec.push_back(a); 
} 

(tương tự cho chuỗi và vân vân) Tôi cố gắng đẩy tất cả vào một vector. Tôi đã thử

std::vector<Argument* > vec; 
std::vector<Argument<typename T>* > vec; 
std::vector<Argument<>* > vec; 

nhưng không có gì trong số này có vẻ hiệu quả. Có cách nào để làm việc này không? Cảm ơn trước.

Trả lời

13

Tùy chọn 1: đảm bảo rằng tất cả các loại đối số khác nhau lấy được từ một lớp cơ sở và sử dụng con trỏ đến lớp đó. Lưu ý rằng tùy chọn này có rủi ro về quản lý bộ nhớ. Bạn có thể muốn làm cho nó an toàn hơn bằng cách sử dụng boost :: shared_ptr thay vì con trỏ. Nếu không, bạn phải tự dọn dẹp khi một mục bị xóa khỏi vectơ.

Lựa chọn 2 (yêu thích cá nhân của tôi): sử dụng để thực hiện một Boost.Variant typedef của tất cả các loại đối số có thể và sử dụng typedef mà như kiểu lập luận trong std :: vector

typedef boost::variant<ArgumentType1, ArgumentType2, ArgumentType3> ArgumentType; 
std::vector<ArgumentType> vec; 
+0

Có vẻ như tôi đã sai khi tôi nghĩ rằng các mẫu được tạo để có "tất cả các loại" trong tầm tay. Vì không có Boost được sử dụng trong dự án này nhưng tôi sẽ gắn bó với thừa kế. thx – DaClown

+0

'std :: variant' có sẵn từ C++ 17. http://en.cppreference.com/w/cpp/utility/variant – biowep

4

Bạn có thể sử dụng boost :: biến thể (http://www.boost.org/doc/libs/1_38_0/doc/html/variant.html)
hoặc đẩy mạnh :: bất kỳ (http://www.boost.org/doc/libs/1_38_0/doc/html/any.html) loại

hoặc void * - xấu xí và không an toàn kiểu
hoặc thực hiện kiểu generic riêng mà sẽ có một giao diện và triển khai templated khác nhau và sẽ lưu trữ con trỏ trên giao diện này.

Nhưng tôi không chắc rằng việc sử dụng các loại tương tự là thiết kế tốt.

6

Cách đơn giản nhất để làm điều này sẽ có một lớp đối số cơ sở, mà không phải là templated, và sau đó có các kiểu dữ liệu cụ thể xuất phát từ nó. (Bạn thậm chí có thể làm cho phiên bản templated bắt nguồn từ lớp cơ sở trực tiếp và chỉ sử dụng hai lớp đó.) Sau đó, bạn lưu trữ chúng dưới dạng con trỏ trong một vectơ.

Điều này yêu cầu phải có một số loại chức năng để truy cập các giá trị đối số và thực hiện bất kỳ chuyển đổi nào theo yêu cầu.

Các vấn đề liên quan