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 サイトの他の関連記事を参照してください。