我想確切的術語因爲你需要的是「模板協方差」,這意味着如果B繼承自A,那麼T<B>
繼承自T<A>
。在C++中情況並非如此,Java和C#泛型也是如此。
有一個很好的理由來避免模板協方差:這將簡單地刪除模板類中的所有類型安全。讓我用下面的例子說明一下:
//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!
}
因此,你應該考慮T<A>
和T<B>
作爲完全無關的類型,無論A和B
之間的關係
那麼你怎麼能解決您遇到的問題」重新面對?在Java和C#中,你可以使用分別界通配符和約束:
//Java code
Bar(Container<? extends Interface) {...}
//C# code
Bar<T>(Container<T> container) where T : Interface {...}
下一個C++標準(被稱爲C++ 1X(以前的C++ 0x))最初包含一個更強大機制名爲Concepts,這可以讓開發人員對模板參數強制實施語法和/或語義要求,但不幸的是推遲到了以後的日期。但是,Boost有一個Concept Check library可能會讓你感興趣。
儘管如此,對於您遇到的問題,概念可能有點矯枉過正,但使用@gf建議的簡單靜態斷言可能是最佳解決方案。
*更新:自.NET Framework 4以來,有可能標記通用參數爲covariant or contravariant。
模板不是多態的。不像在運行時綁定的多態對象,模板在編譯時綁定。 – 2010-02-04 22:12:43
相關問題:http://stackoverflow.com/questions/1289167/template-polymorphism-not-working http://stackoverflow.com/questions/639248/c-covariant-templates – 2010-02-05 10:41:30