首页 > 后端开发 > C++ > 为什么 C 不支持模板协变,以及在使用多态模板时如何解决由此产生的类型安全问题?

为什么 C 不支持模板协变,以及在使用多态模板时如何解决由此产生的类型安全问题?

Patricia Arquette
发布: 2024-10-28 08:14:02
原创
595 人浏览过

Why doesn't C   support template covariance, and how can we address the resulting type safety issues when working with polymorphic templates?

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中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板