Tôi nghĩ rằng thuật ngữ chính xác cho những gì bạn cần là "hiệp phương sai khuôn mẫu", có nghĩa là nếu B kế thừa từ A, thì bằng cách nào đó, T<B>
được kế thừa từ T<A>
. Đây không phải là trường hợp trong C++, cũng không phải là với Java và C# generics *.
Có một lý do chính đáng để tránh hiệp phương sai khuôn mẫu: điều này sẽ loại bỏ tất cả các loại an toàn trong lớp mẫu. Hãy để tôi giải thích với các ví dụ sau:
//Assume the following class hierarchy
class Fruit {...};
class Apple : public Fruit {...};
class Orange : public Fruit {...};
//Now I will use these types to instantiate a class template, namely std::vector
int main()
{
std::vector<Apple> apple_vec;
apple_vec.push_back(Apple()); //no problem here
//If templates were covariant, the following would be legal
std::vector<Fruit> & fruit_vec = apple_vec;
//push_back would expect a Fruit, so I could pass it an Orange
fruit_vec.push_back(Orange());
//Oh no! I just added an orange in my apple basket!
}
Do đó, bạn nên cân nhắc T<A>
và T<B>
loại như hoàn toàn không liên quan, không phụ thuộc vào mối quan hệ giữa A và B.
Vậy làm thế nào bạn có thể giải quyết vấn đề bạn' lại phải đối mặt? Trong Java và C#, bạn có thể sử dụng tương ứng ký tự đại diện bị chặn và chế:
//Java code
Bar(Container<? extends Interface) {...}
//C# code
Bar<T>(Container<T> container) where T : Interface {...}
Tiếp theo C++ Standard (gọi là C++ 1x (trước đây là C++ 0x)) ban đầu chứa một thậm chí mạnh mẽ hơn cơ chế có tên Concepts, điều đó sẽ cho phép nhà phát triển thực thi các yêu cầu về cú pháp và/hoặc ngữ nghĩa đối với các tham số mẫu, nhưng tiếc là đã bị trì hoãn đến một ngày sau đó. Tuy nhiên, Boost có số Concept Check library mà bạn có thể quan tâm.
Tuy nhiên, khái niệm có thể hơi quá mức đối với sự cố bạn gặp phải, việc sử dụng xác nhận tĩnh đơn giản như được đề xuất bởi @gf có lẽ là giải pháp tốt nhất.
* Cập nhật: Vì .Net Framework 4, có thể đánh dấu các thông số chung là covariant or contravariant.
Mẫu không đa hình. Các mẫu được ràng buộc tại thời gian biên dịch, không giống như các đối tượng đa hình bị ràng buộc tại thời gian chạy. –
Các câu hỏi liên quan: http://stackoverflow.com/questions/1289167/template-polymorphism-not-working http://stackoverflow.com/questions/639248/c-covariant-templates –