Heim >Backend-Entwicklung >C++ >Warum unterstützt C keine Template-Kovarianz und wie können wir die daraus resultierenden Typsicherheitsprobleme bei der Arbeit mit polymorphen Templates beheben?

Warum unterstützt C keine Template-Kovarianz und wie können wir die daraus resultierenden Typsicherheitsprobleme bei der Arbeit mit polymorphen Templates beheben?

Patricia Arquette
Patricia ArquetteOriginal
2024-10-28 08:14:02596Durchsuche

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

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!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn