Vorlagen und Polymorphismus in C
Betrachten Sie die folgende Klassenstruktur:
<code class="cpp">class Interface { // ... }; class Foo : public Interface { // ... }; template <class T> class Container { // ... };</code>
Ein Konstruktor einer anderen Klasse Bar ist wie folgt definiert:
<code class="cpp">Bar(const Container<Interface>& bar) { // ... }</code>
Beim Versuch, den Konstruktor jedoch wie folgt aufzurufen:
<code class="cpp">Container<Foo> container(); Bar *temp = new Bar(container);</code>
wir stoßen wir auf den Fehler „Keine passende Funktion“.
Polymorphismus in Vorlagen
Das Konzept des Polymorphismus in Vorlagen oder der Vorlagenkovarianz würde bedeuten, dass, wenn Klasse B von Klasse A erbt, T erbt ebenfalls von T. Dies ist jedoch in C oder anderen Sprachen wie Java oder C# nicht der Fall.
Grund für fehlende Template-Kovarianz
Das Fehlen von Template-Kovarianz wird durch die gerechtfertigt Typsicherheit muss gewahrt bleiben. Betrachten Sie das folgende Beispiel:
<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>
Dies zeigt das Potenzial für unsicheres Verhalten, wenn Vorlagen kovariant wären. Daher ist T und T werden als völlig unterschiedliche Typen betrachtet, unabhängig von der Beziehung zwischen A und B.
Lösung des Problems
Ein Ansatz zur Lösung des Problems in Java und C# ist die Verwendung von Bounded Platzhalter bzw. Einschränkungen:
<code class="java">Bar(Container<? extends Interface) {...}
<code class="csharp">Bar<T>(Container<T> container) where T : Interface {...}</code>
In C kann die Boost Concept Check-Bibliothek ähnliche Funktionen bereitstellen. Die Verwendung einer einfachen statischen Zusicherung kann jedoch eine praktischere Lösung für das spezifische Problem sein:
<code class="cpp">static_assert(std::is_base_of<Interface, Foo>::value, "Container must hold objects of type Interface or its derived classes.");</code>
Das obige ist der detaillierte Inhalt vonWarum unterstützt C keine Template-Kovarianz und wie können wir die daraus resultierenden Typsicherheitsprobleme bei der Arbeit mit polymorphen Templates beheben?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!