C ++ entspricht der Verwendung von T extends Klasse für einen Java-Parameter / Rückgabetyp

8

Um in Java eine Funktion zu erstellen, die ein Objekt zurückgibt, das den gleichen Typ wie ein Parameter hat und eine bestimmte Klasse erweitert, würde ich Folgendes eingeben:

%Vor%

Gibt es ein C ++ -Äquivalent?

Mit anderen Worten, wie mache ich eine Funktion, die jede Klasse übernimmt, die eine bestimmte Klasse erweitert und denselben Typ zurückgibt? (Dies ist für abstrakte / rein virtuelle Klassen).

    
ricky3350 06.06.2015, 20:31
quelle

3 Antworten

8

Wir können enable_if hier verwenden, wenn Ihnen C ++ 11 oder höher zur Verfügung steht

%Vor%

Zum Beispiel:

%Vor%

Live-Demo

    
AndyG 06.06.2015, 20:43
quelle
8

Technisch, wie die anderen Antworten zeigen, gibt es Möglichkeiten, sie zur Kompilierzeit auf Subtypen eines bestimmten Typs zu beschränken. Allerdings würden Sie die meiste Zeit nur tun

%Vor%

ohne Angabe einer Grenze.

In Java werden Grenzen für Generika benötigt, da die generische Klasse oder Methode unabhängig von ihren Verwendungen kompiliert wird. Generische Klassen oder Methoden werden einmal in einer einzigen Version im Bytecode kompiliert. Dabei handelt es sich um eine einzelne Version, die alle Argumente verarbeiten kann, die von Aufrufern ausgegeben werden, die die Grenzen ihrer Deklaration erfüllen.

Der Compiler muss die Verwendung des Typs T im Hauptteil der Methode, wie Methodenaufrufe, Feldzugriffe etc., typenüberprüfen, ohne zu wissen, was T ist. Daher müssen Sie eine Grenze für den Compiler angeben B. erfüllt sein, dass ein Methodenaufruf gültig ist, da er für alle Typen definiert ist, die diese Bindung erfüllen. Wenn Sie beispielsweise im Körper der Methode den Ausdruck bar.baz() hatten, lässt der Compiler Sie nur kompilieren, wenn der Typ MyClass (und damit alle Subtypen davon) die Methode .baz() ; Hätten Sie keine Grenzen angegeben, würde der Compiler beschweren, dass Object (die implizite obere Grenze) keine Methode .baz() hat.

C ++ Vorlagen sind anders. Die Template-Klasse oder -Funktion wird für jedes andere Typargument, für das sie verwendet wird, "instanziiert" (erneut kompiliert). Zum Zeitpunkt des Kompilierens des Rumpfs der Funktion für einen bestimmten T weiß der Compiler, was T ist, und kann die Verwendung dieses Typs direkt überprüfen.

Wenn Sie also im Körper der Funktion den Ausdruck bar.baz() hätten, wäre das in Ordnung. Wenn Sie diese Funktion mit T als Typ verwendet haben, der MyClass erweitert, wird die Kompilierung ordnungsgemäß ausgeführt, da ein solcher Typ eine .baz() hat. Wenn Sie diese Funktion mit einem Typ verwenden, der kein .baz() enthält, wird es bei dieser Verwendung nicht kompiliert. Wenn Sie die Funktion versehentlich mit einem Typ verwenden, der MyClass nicht erweitert, aber einen .baz() hat, dessen Parametertypen und Rückgabetyp mit der Art und Weise übereinstimmen, in der Sie ihn verwenden, wird er ebenfalls kompiliert; aber das ist nicht unbedingt eine schlechte Sache. C ++ - Vorlagen werden normalerweise nicht mit Typhierarchien verwendet, sondern mit Anforderungen an die Art, die der Typ bereitstellen muss. So wird zum Beispiel ein Sortieralgorithmus nicht verlangen, dass sein Container und / oder Elementtyp einen bestimmten Typ erweitert, sondern dass der Container bestimmte Merkmale bereitstellt (z. B. Operator für einen Index mit wahlfreiem Zugriff) und der Elementtyp bestimmte Merkmale (z ein Kleiner-als-Operator).

    
newacct 03.02.2016 09:35
quelle
0

Da ich die angenommene Antwort nicht kommentieren kann, gebe ich eine neue Antwort, die darauf aufbaut.

Die Vorlagenparameter können vereinfacht werden, indem die Bedingung enable_if zum Standardtypvorlagenparameter anstelle von nullptr .

%Vor%     
Matthew Borger 02.02.2016 22:14
quelle

Tags und Links