Templates
-
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; }
-
Dein Programm funktioniert einwandfrei.
Und der Header für strcmp heißt übrigens cstring.
-
Nathan schrieb:
Dein Programm funktioniert einwandfrei.
Und der Header für strcmp heißt übrigens cstring.Danke für dein Feedback. Vermutlich liegt es dann beim Code::Blocks 12.11, ich probiere es heute abend mal auf Netbeans und VS aus.
-
Cpp_Anfaeger schrieb:
Danke für dein Feedback. Vermutlich liegt es dann beim Code::Blocks 12.11, ich probiere es heute abend mal auf Netbeans und VS aus.
Nein, das liegt weder an deiner IDE (die damit überhaupt gar nichts zu tun hat) noch direkt an deinem Compiler (bzw. der Standardbibliothek, die dieser mitbringt). Das liegt da dran, dass string.h auch korrekt ist, sofern man sich auf die Kompatiblitätsfeatures von C++ verlässt. Diese sind jedoch ausdrücklich "deprecated":
C++11, appendix D, 2 schrieb:
These are deprecated features, where deprecated is defined as: Normative for the current edition of the
Standard, but not guaranteed to be part of the Standard in future revisions.C++11, appendix D.5 schrieb:
- For compatibility with the C standard library and the C Unicode TR, the C++ standard library provides
the 25 C headers, as shown in Table 154.
Table 154 — C headers
<assert.h>
<complex.h>
<ctype.h>
<errno.h>
<fenv.h>
<float.h>
<inttypes.h>
<iso646.h>
<limits.h>
<locale.h>
<math.h>
<setjmp.h>
<signal.h>
<stdalign.h>
<stdarg.h>
<stdbool.h>
<stddef.h>
<stdint.h>
<stdio.h>
<stdlib.h>
<string.h>
<tgmath.h>
<time.h>
<uchar.h>
<wchar.h>
<wctype.h>- Every C header, each of which has a name of the form name.h, behaves as if each name placed in the standard
library namespace by the corresponding cname header is placed within the global namespace scope. It is
unspecified whether these names are first declared or defined within namespace scope (3.3.6) of the namespace
std and are then injected into the global namespace scope by explicit using-declarations (7.3.3). - [ Example: The header <cstdlib> assuredly provides its declarations and definitions within the namespace
std. It may also provide these names within the global namespace. The header <stdlib.h> assuredly
provides the same declarations and definitions within the global namespace, much as in the C Standard. It
may also provide these names within the namespace std. — end example ]
Aber eigentlich heißt der Header cstring:
C++11, 21.7 schrieb:
- Tables 74, 75, 76, 77, 78, and 79 describe headers <cctype>, <cwctype>, <cstring>, <cwchar>, <cstdlib>
(character conversions), and <cuchar>, respectively. - The contents of these headers shall be the same as the Standard C Library headers <ctype.h>, <wctype.h>,
<string.h>, <wchar.h>, and <stdlib.h> and the C Unicode TR header <uchar.h>, respectively, with the
following modifications:
[...]
- For compatibility with the C standard library and the C Unicode TR, the C++ standard library provides
-
Danke, ich habe die Headerdatei gegen cstring ausgewechselt, aber in der Ausgabe steht immer noch was Falsches

Der kleinere Wert ist: b (es müsste aber nach meinem Verständis stehen: baaa)
und befindet sich im Objekt: baaa (es müsste aber hier die Adresse der betreff. Variablen stehen: 0x....)
-
Du gibst
char*aus, das verhält sich bezüglich I/O anders alsT*. Es wird nämlich als String interpretiert. Mit der Dereferenzierung hast du ein einzelnes Zeichen vom Typchar.Um die Adresse auszugeben, benutze
static_cast<void*>.
-
Nexus schrieb:
Du gibst
char*aus, das verhält sich bezüglich I/O anders alsT*. Es wird nämlich als String interpretiert. Mit der Dereferenzierung hast du ein einzelnes Zeichen vom Typchar.Um die Adresse auszugeben, benutze
static_cast<void*>.Ich weiß nicht, ob das syntaktisch richtig ist:
error: invalid static_cast from type 'const char' to type 'void'**
-
constvergessen
-
Nexus schrieb:
constvergessenOh Mann ... zu blöd, um die Fehlermeldung zu interpretieren. Danke für den Hinweis

Ich habe es angewendet:
cout << "Der kleinere Wert ist: " << static_cast <const char*> (smallest) << " und befindet sich im Objekt: " << static_cast <const void*> (smallest) << endl;Leider klappt es sauber wieder nur für:
const char value1[] = "Aachen"; // C-Style const char value2[] = "Muenchen";bei der Form zeigt er eine andere Adresse an:
const char *value1 = "Muenchen"; // C-Style const char *value2 = "Aachen";und für die Form kratzt er ganz ab:
int value1 = 2; int value2 = 100;Ist doch zum Mäuse-Melken diese ganzen Zeiger

Ich versuche die ganze Zeit es so hinzubekommen, dass ich die Funktion findMinimum() einheitlich immer auf dieselbe Art und Weise verwenden kann, egal was man als Parameter übergibt. Und rauskommen soll es auch einheitlich, ohne nachdenken zu müssen, ob ich was für einen Typ habe.