ホームページ > バックエンド開発 > C++ > C がテンプレートの共分散をサポートしていないのはなぜですか?また、多態性テンプレートを使用する場合に生じる型安全性の問題にどのように対処すればよいでしょうか?

C がテンプレートの共分散をサポートしていないのはなぜですか?また、多態性テンプレートを使用する場合に生じる型安全性の問題にどのように対処すればよいでしょうか?

Patricia Arquette
リリース: 2024-10-28 08:14:02
オリジナル
566 人が閲覧しました

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 がクラス A から継承されることを意味します。同様に T から継承します。ただし、これは 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 は次のとおりである。およびTB< A と B の関係に関係なく、完全に異なる型とみなされます。

問題の解決

Java と C# の問題を解決する 1 つのアプローチは、制限付きを使用することです。ワイルドカードと制約はそれぞれ:

<code class="java">Bar(Container<? extends Interface) {...}
ログイン後にコピー
<code class="csharp">Bar<T>(Container<T> container) where T : Interface {...}</p>
<p>C では、Boost Concept Check ライブラリが同様の機能を提供できます。ただし、発生した特定の問題に対しては、単純な静的アサートを使用する方がより実用的な解決策となる可能性があります。</p>
<pre class="brush:php;toolbar:false"><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 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート