C模板多态性

我有这种结构的类。

class Interface{
...
}

class Foo : public Interface{
...
}

template <class T>
class Container{
...
}

我有一个其他类Bar的这个构造函数。

Bar(const Container<Interface> & bar){
...
}

当我调用构造函数这种方式我得到“无匹配函数”的错误。

Container<Foo> container ();

Bar * temp = new Bar(container);

哪里不对?是不是模板多态?

我认为你需要的确切术语是“模板协方差”,意味着如果B从A继承,则不知何故T&继承自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

http://stackoverflow.com/questions/2203388/c-templates-polymorphism

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:C模板多态性