C 中的模板和多态性
考虑以下类结构:
<code class="cpp">class Interface { // ... }; class Foo : public Interface { // ... }; template <class T> class Container { // ... };</code>
其他类的构造函数Bar 定义为:
<code class="cpp">Bar(const Container<Interface>& bar) { // ... }</code>
但是,当尝试按如下方式调用构造函数时:
<code class="cpp">Container<Foo> container(); Bar *temp = new Bar(container);</code>
我们遇到“无匹配函数”错误。
模板中的多态性
模板中的多态性或模板协方差的概念意味着如果类 B 继承自类 A,则 T同样继承自T A 。然而,在 C 或 Java 或 C# 等其他语言中,情况并非如此。
缺乏模板协方差的原因
缺乏模板协方差的理由是需要维护类型安全。考虑以下示例:
<code class="cpp">// Class hierarchy class Fruit {...}; class Apple : public Fruit {...}; class Orange : public Fruit {...}; // Template instantiation using std::vector int main() { std::vector<Apple> apple_vec; apple_vec.push_back(Apple()); // Valid // With covariance, the following would be allowed std::vector<Fruit>& fruit_vec = apple_vec; // Adding an Orange to the vector fruit_vec.push_back(Orange()); // Incorrect addition of an orange to an apple vector }</code>
这表明如果模板是协变的,则可能会出现不安全行为。因此,T A 是和T B 。无论 A 和 B 之间的关系如何,都被视为完全不同的类型。
解决问题
在 Java 和 C# 中解决问题的一种方法是使用有界通配符和约束分别为:
<code class="java">Bar(Container<? extends Interface) {...}
<code class="csharp">Bar<T>(Container<T> container) where T : Interface {...}</code>
在 C 语言中,Boost Concept Check 库可以提供类似的功能。然而,对于遇到的特定问题,使用简单的静态断言可能是更实用的解决方案:
<code class="cpp">static_assert(std::is_base_of<Interface, Foo>::value, "Container must hold objects of type Interface or its derived classes.");</code>
以上是为什么 C 不支持模板协变,以及在使用多态模板时如何解决由此产生的类型安全问题?的详细内容。更多信息请关注PHP中文网其他相关文章!