2017-04-20 2 views
2

heute in Theorie der Programmiersprache Klasse wir dieses Verhalten in Java gesehen haben:Parametric Methoden mit verschiedenen Subtypen

public class Es { 
    ... 
    <Y> Y choose(Y y1, Y y2){ 
     Y returnVal; 
     if("some test"){ returnVal = y1;} else{ returnVal = y2;} 
     return returnVal; 
    } 
} 

In Main:

Es c = new Es(); 
Integer i = 3; 
Float f = (float) 4.5; 
Number n = c.choose(i, f); 

Wo die "unglaublich" ist, dass das Verfahren muss Wählen Sie zwischen Integer und Float für den parametrischen Typ Y und entscheiden Sie sich für den nächsten Supertyp, nämlich Number.

Ich mag würde dies in C++ reproduzieren, aber ich bin fest ...

+2

Diese werden als [Generische Methoden] (https://docs.oracle.com/javase/tutorial/java/generics/methods.html) bezeichnet. Ich glaube, dass Sie dies in einer C++ - Vorlage konvertieren möchten, aber ich habe diese seit langer Zeit nicht mehr verwendet. Aber das könnte Ihnen helfen, etwas zu recherchieren – AxelH

Antwort

4

Vorlagen versuchen nicht, Typen anzupassen, wenn sie nicht übereinstimmen. Deshalb ist eine einfache Implementierung wie folgt aus:

template <class Y> 
Y choose(Y y1, Y y2) { 
    // ... 
} 

mit dem folgenden Fehler schlägt fehl:

main.cpp:8:5: fatal error: no matching function for call to 'choose' 
    choose(1, 2.5f); 
    ^~~~~~ 
main.cpp:3:3: note: candidate template ignored: 
        deduced conflicting types for parameter 'Y' ('int' vs. 'float') 

Was Sie tun möchten, ist die Funktion Vorlage in beiden Typen nehmen lassen, dann lösen die gemeinsame Typ:

template <class Y1, class Y2> 
auto choose(Y1 y1, Y2 y2) { 
    using Y = std::common_type_t<Y1, Y2>; 

    Y returnVal; 

    if("some test") { 
     returnVal = y1; 
    } else { 
     returnVal = y2; 
    } 

    return returnVal; 
} 

Eine gute Idee ist die Funktion SFINAE freundlich, indem auch die Aufhebung des Typs Abzug in seine Unterschrift zu machen:

template <class Y1, class Y2> 
std::common_type_t<Y1, Y2> choose(Y1 y1, Y2 y2) { 
    // Same as before 
} 
-1

eine Template-Funktion verwenden. Der C++ Code, der das gleiche wie Ihr Java-Code tut, ist wirklich bemerkenswert ähnlich dem Java-Code selbst:

template <typename Y> 
Y choose(Y y1, Y y2) { 
    Y returnVal; 
    if("some test"){ returnVal = y1;} else{ returnVal = y2;} 
    return returnVal; 
} 

Sie können es einfach nennen, wie Sie es in Java-Compiler den richtigen Typ ableiten:

choose(1,2); //With two ints 
choose("hi","bye"); //With two char*s. 

HINWEIS: Semantisch, C++ Vorlagen sind ganz verschieden von Java Generika. Java-Generics werden mit Type-Erasure implementiert - die JRE hat zur Laufzeit keine Ahnung von den Typparametern, während C++ - Vorlagen tatsächlich jedes Mal, wenn die Vorlage für einen anderen Typ verwendet wird, eine separate Funktion oder Klasse erstellen. Siehe this answer.

Edit: Ich missverstanden Ihre Frage. Unglücklicherweise glaube ich nicht, dass C++ das gewünschte Verhalten hat; Sie müssen explizit angeben, dass beide der Obertyp sind.

+0

"die Methode muss zwischen Integer und Float für den parametrischen Typ Y wählen und entscheidet sich für den nächsten Super-Typ" - das ist hier nicht getan. – Quentin

+0

@Quentin Ich glaube nicht, dass es eine äquivalente Zahl Super-Typ in C++ gibt. – ostrichofevil

+0

@strichofeevil Nein, aber Sie können eine Vorlage erstellen, deren Standardimpl einen Kompilierungsfehler verursacht, wenn sie verwendet wird, und dann Spezialisierungen – UKMonkey

Verwandte Themen