首頁 > 後端開發 > C++ > 為什麼 C 不支援模板協變,以及在使用多型模板時如何解決由此產生的型別安全問題?

為什麼 C 不支援模板協變,以及在使用多型模板時如何解決由此產生的型別安全問題?

Patricia Arquette
發布: 2024-10-28 08:14:02
原創
610 人瀏覽過

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
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板