Programiersprache für Anfänger
-
hustbaer schrieb:
Ob es geht hängt wohl vom Compiler ab. Mit MSVC 2005 geht es z.B. nicht.
ist das nicht eher eine frage der stl-implementation? wie auch immer, c++ ist für anfänger absolut nicht geeignet. ich hoffe, darüber sind wir uns jetzt einig. ihr seht ja selbst, welch einfache dinge (im vergleich zu anderen sprachen/systemen) in c++ viele, viele fragen aufwerfen.
-
ist das nicht eher eine frage der stl-implementation?
Hm. Pfuh. Ja, das zumindest auch. Obwohl ...
Beispiel (mit MSVC 2005):
#include <iostream> // geht mit array-typen template <class T> T const& min1(T const& a, T const& b) { std::cout << "T = " << typeid(T).name() << std::endl; if (a < b) // beim vergleich zerfällt "char const (&)[2]" anscheinend zu "char const*", return a; // es werden also zeiger verglichen, nicht der array-inhalt else return b; } // geht NICHT mit array-typen template <class T> T const& min2(T const& a, T const& b) { std::cout << "T = " << typeid(T).name() << std::endl; return a < b ? a : b; // MSVC 2005 ermittelt hier als typ des ausdrucks // "bool ? char const (&)[2] : char const (&)[2]" anscheinend // einfach "char const*" - warum auch immer } // geht mit array-typen, obwohl's IMO eigentlich äquivalent zu min2 sein sollte template <class T> T const& min3(T const& a, T const& b) { std::cout << "T = " << typeid(T).name() << std::endl; return a < b ? static_cast<T const&>(a) : static_cast<T const&>(b); } template <class T> void show_type(T) { std::cout << "T = " << typeid(T).name() << std::endl; } template <class T> void show_type_cref(T const&) { std::cout << "T = " << typeid(T).name() << std::endl; } int main() { show_type("foo"); char* s = "foo"; // geht (korrekter-, wenn auch unsinnigerweise)! man beachte aber dass show_type("foo") "char const *" als Typ ausgibt! show_type_cref("foo"); typedef char const (&T)[2]; T x = min1("a", "b"); std::cout << x << std::endl; T y = min1("d", "c"); std::cout << y << std::endl; // T z = min2(a, b); // geht nicht T z = min3("e", "f"); // geht wieder?!? return 0; }
Output:
T = char const * T = char const [4] T = char const [2] b T = char const [2] c T = char const [2]
Bei einigen Dingen bin ich mir hier nicht ganz sicher...
- Welcher Typ sollte bei show_type("foo") rauskommen?
- Welcher Typ sollte bei show_type_cref("foo") rauskommen?
- Sollte ein "const-ref-auf-array" Typ bei "a < b ? a : b" wirklich zu "T const*" zerfallen??? Und darf es einen Unterschied machen ob man explizit nochmal nen Cast schreibt (min2 vs. min3)? IMO müsste sich zumindest min2 gleich wie min3 verhalten...
- Muss std::min die Parameter (und den Returnwert) per const-ref nehmen, oder wäre ein einfaches "template <class T> T min(T, T)" auch OK?
Und nochmal zu 1: IMO dürfte der Typ auf jeden Fall nicht const sein, da ein String-Literal laut Standard nicht const ist. Es ist zwar "gut" dass wenigstens hier das const "magischerweise" dazukommt, da die Regel "String Literale sind nicht const" sowieso Blödsinn ^4 ist, aber komisch ist es schon irgendwie.
Alles sehr seltsam...
wie auch immer, c++ ist für anfänger absolut nicht geeignet
ACK. Wobei hinzuzufügen ist dass Anfäger in jeder Sprache kaum ein 100% korrektes Programm hinbekommen werden, welches auch alle Spezial- und Fehlerfälle korrekt behandelt
-
hustbaer schrieb:
Und nochmal zu 1: IMO dürfte der Typ auf jeden Fall nicht const sein, da ein String-Literal laut Standard nicht const ist. Es ist zwar "gut" dass wenigstens hier das const "magischerweise" dazukommt, da die Regel "String Literale sind nicht const" sowieso Blödsinn ^4 ist,
wohl aus kompatiblitätsgründen, damit sowas wie
char *p = "hello";
funzt und damit man funktionen mit string-literalen aufrufen kann, die 'nen char* erwarten. sowas wie"hello"[1] = 'a';
wird wohl compilieren, aber trotzdem crashen (hab's nicht probiert, mangels c++ compiler hier).hustbaer schrieb:
...aber komisch ist es schon irgendwie.
Alles sehr seltsam...in der tat. da ist mal wieder dieses erstaunen: 'bin ich wirklich der erste, der das versucht?', was man in C++ ziemlich oft erleben kann.
-
~fricky schrieb:
in der tat. da ist mal wieder dieses erstaunen: 'bin ich wirklich der erste, der das versucht?', was man in C++ ziemlich oft erleben kann.
Nö, das bist du sicherlich nicht. Aber wenn man länger C++ programmiert, gibt es eine relativ einfache Regel sich vor großen Ärger zu schützen. Man sollte keine C-Altlasten ohne groß nachzudenken mit C++ Mechanismen verwenden. Das geht oftmals in die Hose.
-
hustbaer schrieb:
- Welcher Typ sollte bei show_type("foo") rauskommen?
String Literale sind vom Type "array of n const char" bzw. "wchar_t" und sind static. Siehe §2.13.4 Absatz 1.
-
~john schrieb:
hustbaer schrieb:
- Welcher Typ sollte bei show_type("foo") rauskommen?
String Literale sind vom Type "array of n const char" bzw. "wchar_t" und sind static. Siehe §2.13.4 Absatz 1.
Und wie ist dann geregelt dass die Zuweisung
char* s = "foo";
legal ist?
EDIT: OK, hab den Absatz gefunden. Wieder einer dieser Hacks um kompatibel zu C zu bleiben. *kopf-schüttel*
-
~john schrieb:
~fricky schrieb:
in der tat. da ist mal wieder dieses erstaunen: 'bin ich wirklich der erste, der das versucht?', was man in C++ ziemlich oft erleben kann.
Nö, das bist du sicherlich nicht. Aber wenn man länger C++ programmiert, gibt es eine relativ einfache Regel sich vor großen Ärger zu schützen. Man sollte keine C-Altlasten ohne groß nachzudenken mit C++ Mechanismen verwenden. Das geht oftmals in die Hose.
ja, das schon. aber es nur ein bruchteil der möglichen fehlerquellen. schau doch mal hier in's C++ unterforum. ich lese es zwar ziemlich selten, aber jedesmal wenn ich mir's anschaue, weiss ich nicht, ob ich lachen oder weinen soll. nicht wegen der fragen, sondern wegen der antworten.