Templates
-
Cpp_Anfaeger schrieb:
Bashar schrieb:
int temp = findMinimum(2, 3); // C++98 auto temp = findMinimum(2, 3); // C++11Ahh, auto ... danke!
mit int temp würde mir der String vorloren gehen, dann müsste ich wieder zurückrechnen

Das int war ja nur ein Beispiel für den Aufruf 2, 3.
Für Strings muss der Rückgabetyp natürlich entsprechend angepasst werden.
Dein Programm wird übrigens nicht funktionieren.
-
Nathan schrieb:
Das int war ja nur ein Beispiel für den Aufruf 2, 3.
Für Strings muss der Rückgabetyp natürlich entsprechend angepasst werden.
Dein Programm wird übrigens nicht funktionieren.Ich wollte nur eine Variable für alle Fälle haben und habe es so mit auto gemacht:
#include <iostream> using namespace std; //------------------------------------------------------------------------ // Funktion vergleicht zwei Werte //------------------------------------------------------------------------ template <typename T> T findMinimum(T value1, T value2) { if (value1 < value2) { return value1; } if (value1 > value2) { return value2; } return 0; } //------------------------------------------------------------------------ // Hauptfunkt. //------------------------------------------------------------------------ int main() { #define VALUE1 "John" #define VALUE2 "Jan" auto temp = findMinimum(VALUE1, VALUE2); // geht if (temp !=0) { cout << "Der kleinere Wert ist: " << temp << endl; } else { cout << "Beide sind gleich!" << endl; } getwchar(); return 0; }
-
Marthog schrieb:
Auch wenn das hier nicht die Frage ist: Verwende nicht #define für Konstanten und bei dem vergleich, werden nur die Addressen der Pointer verglichen. Wenn du alphabetisch vergleichen willst, musst du std::string nehmen oder std::lexicographical_compare.
Danke, habe das gerade festgestellt ... ich wollte es halt mit Templates alles auf einen Schlag haben
-
Wenn beide Werte gleich sind, gibst du 0 zurück? Was ist denn das für ein Minimum?
Dass deine Funktion für Strings überhaupt kompiliert, hast du auch nur dem Spezialfall zu verdanken, dass die Null als Nullzeigerliteral interpretiert wird. Mach einfach if-else, mehr als eine Abfrage ist sowieso nicht notwendig.
Übrigens: In C++ solltest du
constfür Konstanten benutzen.#defineist für Textersetzungen, wo du sie wirklich brauchst.
-
Nexus schrieb:
Übrigens: In C++ solltest du
constfür Konstanten benutzen.#defineist für Textersetzungen, wo du sie wirklich brauchst.Danke, das mit const gucke ich mir an.
Nexus schrieb:
Wenn beide Werte gleich sind, gibst du 0 zurück? Was ist denn das für ein Minimum?
Null soll für false stehen (kein Minimum gefunden).
-
Cpp_Anfaeger schrieb:
Null soll für false stehen (kein Minimum gefunden).
Die kleinere Zahl von 5 und 5 ist 0? Von -5 und -5? Und welches ist die kleinere Zahl von 0 und 1? 0 oder ein Fehler?
-
SeppJ schrieb:
Cpp_Anfaeger schrieb:
Null soll für false stehen (kein Minimum gefunden).
Die kleinere Zahl von 5 und 5 ist 0? Von -5 und -5? Und welches ist die kleinere Zahl von 0 und 1? 0 oder ein Fehler?
Ja, es stimmt mit der Logik nicht ... das mit der Null ist nicht eindeutig. Vllt geht es so (soweit auch const eingebaut), das geht auch mit dem String von C++. Nur mit dem String von C klappt es so nicht:
//---------------------------------------------------------------------- // Thema: Templates // // Beschreibung: Mit Hilfe der Template-Methode lässt es sich // mit der Funktion primitive u. Stringtypen // miteinander vergleichen. Voraussetzung ist, // dass die Probanden vom selben Typ sind! // //----------------------------------------------------------------------- #include <iostream> #include <string> using namespace std; //------------------------------------------------------------------------ // Funktion-Template vergleicht zwei Werte //------------------------------------------------------------------------ template <typename T> const T findMinimum(const T &value1, const T &value2) { if (value1 < value2) { return value1; } if (value1 > value2) { return value2; } return (value1 + value2); } //------------------------------------------------------------------------ // Hauptfunkt. //------------------------------------------------------------------------ int main() { //string value1 = "zaaaaaabbb"; //geht //string value2 = "zaaaaaabbb"; //geht //int value1 = 2; //geht //int value2 = 3; //geht float value1 = 8.7; //geht float value2 = 3.1; //geht // char *value1 = "hjkshdk"; //geht nicht // char *value2 = "kljj"; //geht nicht auto smallest = findMinimum(value1, value2); if (smallest == value1 + value2) { cout << "Gleich!" << endl; } else { cout << "Der kleinere Wert ist: " << smallest << endl; } getwchar(); return 0; }
-
Cpp_Anfaeger schrieb:
Ja, es stimmt mit der Logik nicht
So ist es. Aber dein neuer Vorschlag ist ja fast noch schlimmer. Denk nicht so technisch. Halte dich an die mathematische Definition eines Minimums, die ist schon gut gewählt.
-
SeppJ schrieb:
Cpp_Anfaeger schrieb:
Ja, es stimmt mit der Logik nicht
So ist es. Aber dein neuer Vorschlag ist ja fast noch schlimmer. Denk nicht so technisch. Halte dich an die mathematische Definition eines Minimums, die ist schon gut gewählt.
Wie kann ich denn sonst die Gleichheit feststellen, wenn der Benutzer 2 gleiche Objekte eingibt? Ich muss doch diese Möglichkeit mitberücksichtigen.
-
Cpp_Anfaeger schrieb:
SeppJ schrieb:
Cpp_Anfaeger schrieb:
Ja, es stimmt mit der Logik nicht
So ist es. Aber dein neuer Vorschlag ist ja fast noch schlimmer. Denk nicht so technisch. Halte dich an die mathematische Definition eines Minimums, die ist schon gut gewählt.
Wie kann ich denn sonst die Gleichheit feststellen, wenn der Benutzer 2 gleiche Objekte eingibt? Ich muss doch diese Möglichkeit mitberücksichtigen.
Nein wozu?
min(5,5) == 5
-
qweasdyxc schrieb:
Cpp_Anfaeger schrieb:
SeppJ schrieb:
Cpp_Anfaeger schrieb:
Ja, es stimmt mit der Logik nicht
So ist es. Aber dein neuer Vorschlag ist ja fast noch schlimmer. Denk nicht so technisch. Halte dich an die mathematische Definition eines Minimums, die ist schon gut gewählt.
Wie kann ich denn sonst die Gleichheit feststellen, wenn der Benutzer 2 gleiche Objekte eingibt? Ich muss doch diese Möglichkeit mitberücksichtigen.
Nein wozu?
min(5,5) == 5Theoretisch, ja, wenn man nur den Wert betrachtet... aber wenn ich etwas hätte, wo ich nicht vorher weiß, was drin ist (2 Blackboxen), dann weiß ich nicht, wie miteinander verglichen wird, oder?
-
Cpp_Anfaeger schrieb:
aber wenn ich etwas hätte, wo ich nicht vorher weiß, was drin ist (2 Blackboxen), dann weiß ich nicht, wie miteinander verglichen wird, oder?
Ah, und das Problem löst man, indem man beide Blackboxes addiert?

Ne, Blackbox funktioniert wunderbar hier. Alles, was einen
<-Operator anbietet, kann zur Berechnung eines Minimums benutzt werden.const T& min(const T& lhs, const T& rhs) { if (lhs < rhs) return lhs; else return rhs; }Schau auch, dass du
const T&und nichtconst Tzurückgibst. Top-Level-CV-Qualifikationen bei Rückgabetypen und Parametern sind nämlich sinnlos.
-
Nexus schrieb:
Top-Level-CV-Qualifikationen bei Rückgabetypen und Parametern sind nämlich sinnlos.
ich bin mir nicht sicher ob ich das richtige anspreche und es auch korrekt in erinnerung habe - verzeih mir wenn nicht - aber z.b. ein fall wo die top-level-cv-qualifier beim rückgabetypen einen unterschied machen:
struct Foo { int MyData; Foo(int Data) : MyData(Data) { } }; const Foo operator+ (Foo const& Lhs, Foo const& Rhs) { return Foo(Lhs.MyData + Rhs.MyData); } void Func(Foo const& Lhs, Foo const& Rhs) { if((Lhs + Rhs).MyData = 0) // Ups, sollte ein Vergleich werden. Kompiliert dank const nicht. { // ... } }
-
[quote="Nexus"] Ne, Blackbox funktioniert wunderbar hier. Alles, was einen
<-Operator anbietet, kann zur Berechnung eines Minimums benutzt werden.const T& min(const T& lhs, const T& rhs) { if (lhs < rhs) return lhs; else return rhs; }Das geht so nicht, weil mein Anliegen anders ist ... es geht mir darum sagen zu können, welches "Objekt" kleiner ist u. nicht welcher Wert. Also es geht mir nicht um den Wert (klar über den Wert schließe ich auf das Objekt zurück) und mit dieser Rückgabe habe ich keine Feststellmöglichkeit. Ich weiß, das ist blöd ausgedrückt.
-
ich hab absolut keine ahnung was das bringen soll aber werd glücklich damit:
template<typename T> T const* MyMin(T const* Lhs, T const* Rhs) { if(*Lhs < *Rhs) { return Lhs; } if(*Rhs < *Lhs) { return Rhs; } return nullptr; }das kann man nun noch für
char const*template-spezialisieren und einen lexicographischen vergleich einfügen. keine lust das nun vorzumachen weil ich den sinn beim besten willen nicht sehe.
-
asfsdaf schrieb:
z.b. ein fall wo die top-level-cv-qualifier beim rückgabetypen einen unterschied machen:
Durch das
constverschlimmerst du die Situation. Indem du einen Fehler verhinderst, der nie passiert, deaktivierst du auch gleich Move-Semantik. Siehe hier...Cpp_Anfaeger schrieb:
Das geht so nicht, weil mein Anliegen anders ist ... es geht mir darum sagen zu können, welches "Objekt" kleiner ist u. nicht welcher Wert.
Darum Referenz und nicht Kopie. Wie du von diesem Anliegen darauf kommst, 0 oder die Summe beider Werte zurückzugeben (was absolut keinen Bezug zum Objekt mehr darstellt), verstehe ich erst recht nicht.
Davon abgesehen, welche Anwendung hat eine so abwegig definierte Minimumsfunktion? Wozu brauchst du das?
-
lol davon wusste ich nichts, bin auch effective c++ zum opfer gefallen. danke für die aufklärung. nun hab ich erstmal einiges an code zu ändern...
-
Nexus schrieb:
Cpp_Anfaeger schrieb:
Das geht so nicht, weil mein Anliegen anders ist ... es geht mir darum sagen zu können, welches "Objekt" kleiner ist u. nicht welcher Wert.
Darum Referenz und nicht Kopie. Wie du von diesem Anliegen darauf kommst, 0 oder die Summe beider Werte zurückzugeben (was absolut keinen Bezug zum Objekt mehr darstellt), verstehe ich erst recht nicht
Danke, ihr habt sicher recht. Es ist nicht richtig, einfach irgendetwas zu schnappen, nur um schnell damit zu basteln, was man später nicht mehr nachvollziehen kann.
**Edit:
asfsdaf schrieb:
ich hab absolut keine ahnung was das bringen soll aber werd glücklich damit:
template<typename T> T const* MyMin(T const* Lhs, T const* Rhs) { if(*Lhs < *Rhs) { return Lhs; } if(*Rhs < *Lhs) { return Rhs; } return nullptr; }das kann man nun noch für
char const*template-spezialisieren und einen lexicographischen vergleich einfügen. keine lust das nun vorzumachen weil ich den sinn beim besten willen nicht sehe.nullptr ... finde ich gut
... hatte ich bisher 0 oder NULL geschrieben
-
asfsdaf schrieb:
ich hab absolut keine ahnung was das bringen soll aber werd glücklich damit:
template<typename T> T const* MyMin(T const* Lhs, T const* Rhs) { if(*Lhs < *Rhs) { return Lhs; } if(*Rhs < *Lhs) { return Rhs; } return nullptr; }das kann man nun noch für
char const*template-spezialisieren und einen lexicographischen vergleich einfügen. keine lust das nun vorzumachen weil ich den sinn beim besten willen nicht sehe.Ich habe es soeben mit dem Keywort lexicographical_compare() versucht. Irgendwie blicke ich nicht durch, was da für Ergebnisse heraus kommen.
Ich habe versucht die Template-Funktion zu überladen und verschiedene Value-Werte hin durchgeschickt.
... ***Edit --> siehe unten
-
Ein weiterer Anlauf ...
Ich habe die Templatefunktion angepasst (Referenz-Parameter anstatt Zeiger), damit der Aufruf der Funktionen in main() einheitlich wird.
Es läuft soweit - glaube ich - nur mit Ausgabe stimmt was nicht, wenn ich Strings nach C-Style in die Funktion findMinimum() reinschicke.
Hat jemand eine Idee, was da vor sich geht?
#include <iostream> #include <string> #include <string.h> // wegen strcmp() using namespace std; //------------------------------------------------------------------------ // Template-Funktion vergleicht zwei Werte miteinander (ohne char*) //------------------------------------------------------------------------ template <typename T> T const* findMinimum(const T &value1, const T &value2, int &templ_nr) { templ_nr = 1; if (value1 < value2) { return &value1; } if (value1 > value2) { return &value2; } return nullptr; // wenn beide gleich } //------------------------------------------------------------------------ // Überladung mit normaler Funktion (vergleicht char*) //------------------------------------------------------------------------ const char *findMinimum(const char *value1, const char *value2, int &templ_nr) { templ_nr = 2; /* // Meine Methode string v1 = value1; string v2 = value2; if (v1 < v2) { return value1; } if (v1 > v2) { return value2; } *--------------------------*/ // strcmp - Methode bool result = strcmp(value1, value2); if (result < 0) { return value1; } if (result > 0) { return value2; } //*---------------------------*/ /* // lexicographical_compare - Methode bool result = lexicographical_compare(value1, value1 + sizeof(value1), value2, value2 + sizeof(value2) ); if (result == true) { return value1; } else { // umdrehen, ob eventuell der andere Wert größer ist bool result = lexicographical_compare(value2, value2 + sizeof(value2) , value1, value1 + sizeof(value1) ); if (result == true) { return value2; } } */ return nullptr; // wenn kein Min gefunden -> beide gleich } //------------------------------------------------------------------------ // Hauptfunkt. //------------------------------------------------------------------------ int main() { /* Testbespiele string value1 = "Muenchen"; // C++ Style string value2 = "Aachen"; int value1 = 2; int value2 = 100; const char *value1 = "Muenchen"; // C-Style const char *value2 = "Aachen"; const char value1[] = "Aachen"; // C-Style const char value2[] = "Muenchen"; */ const char value1[] = "baaaaaaaaab"; // C-Style const char value2[] = "baaa"; int templ_nr = 0; cout << "Objekt1-Ort: " << &value1 << " Inhalt: " << value1 << endl; cout << "Objekt2-Ort: " << &value2 << " Inhalt: " << value2 << endl << endl; // Compiler wählt autom. eine passende Methode: auto *smallest = findMinimum(value1, value2, templ_nr); cout << "Template Nr. " << templ_nr << " wurde aufgerufen." << endl << endl; if (smallest != nullptr) { // hier stimmt was nicht mit der Ausgabe, ??? // wenn es sich um char* handelt cout << "Der kleinere Wert ist: " << *smallest << " und befindet sich im Objekt: " << smallest << endl; } else { cout << "Inhalte von beiden sind gleich!" << endl; } getwchar(); return 0; }