vergesst C++ ...
-
Kannst Du mal ein Beispiel nennen, wo man sowas wirklich braucht? Also, in welchen Fällen ist es wirklich unmöglich, den Typ zu wissen? Ich meine, wenn ein Compiler den Rückgabetyp erraten kann, kann das ein Programmierer doch auch, oder?
wenn du ein expression template hast, wirds unheimlich kompliziert.
ich benutze die im moment, und wenn ich da mal nen fehler mache, krieg ich einen typ an den Hals geworfen, der 800(!) und mehr zeichen lang ist. sowas kann man nicht mehr erraten.dann kommt folgendes problem noch dazu:
var=expression_template;
mit dem auto keyword wär das kein problem. ohne auto keyword musst du aus dem expression template einen polymorphen typ basteln den du dann var zuweisen kannst.
wenn nun das expression-template folgende funktion hat:
template<class T,class U> void foo(T,U);
wie willst du das mit einem polymorphen typ durchbringen? template+virtual=müll.
im endeffekt muss ich dann also auf die flexibilität dieses templates verzichten und var folgenden typ geben: Rule<T,U>. Rule selber hat 500 zeilen quellcode, nur(!) um ein expression template speichern zu können, eine sache die mit auto nur eine einzige zeile brauchen würde, und die einem auch noch den virtual overhead erspart.
-
Power Off schrieb:
Na ja, aber was spricht dagegen:
template <class A, class B, class C> void func( A a, B b, C& c ) { c = a * b; } und dann: char a = 2; short b = 7; int c; func( a, b, c ); bzw. func<char,short,int>( a, b, c );
es ist
int c;//autsch, aua, ui, oh, aua, ohweh!
ich wollte doch nicht gezwungen sein, den typ zu wissen.
char a = 2; short b = 7; auto c=func( a, b );
Kannst Du mal ein Beispiel nennen, wo man sowas wirklich braucht? Also, in welchen Fällen ist es wirklich unmöglich, den Typ zu wissen? Ich meine, wenn ein Compiler den Rückgabetyp erraten kann, kann das ein Programmierer doch auch, oder?
haste schon das paper über expression templates von todd Veldhuizen gelesen? muß man eigentlich, ist ja 10 jahre alt und mindestens so wichtig wie modern c++ design.
http://osl.iu.edu/~tveldhui/papers/Expression-Templates/exprtmpl.html
dann kannste dich antemplate<class A, class B> DExpr<DBinExprOp<DExpr<A>, DExpr<B>, DApDivide> > operator/(const DExpr<A>& a, const DExpr<B>& b) { typedef DBinExprOp<DExpr<A>, DExpr<B>,DApDivide> ExprT; return DExpr<ExprT>(ExprT(a,b)); }
erinnern.
ok, es ist immer möglich, den ergebnistyp hinzuschreiben. logischwerweise gibts komplexere sachen, ich nenne die einheitenmitführung, wie von meyers im vorwort zu modern c++ design skizziert, wo man auch noch metaprogrammierung zur bestimmung des rückgabetyps braucht.(Aber ich kapier auch die BOOST Library nicht, ist mir zu unlesbar, aber ist wohl Geschmackssache; ich gehör nicht zu denen, die ständig neue Sprachfeatures lernen, wenn ich sie nicht brauche -- leider; hab lang gebraucht, bis ich mir mal die STL so richtig reingezogen habe)
geht mir ähnlich. stl und boost sind mir so unangenehm, daß ich nicht mehr drauf aufsetze und leiber alles selber mache.
-
volkard schrieb:
aber was ist eigentlich mit
template<typename T,int size> auto findElemAndIKnowItsExistent(T (&arr)[size],T const& toFind){ for(int i=0;i<size;++i) if(arr[i]==toFind) return &arr[i]; //hier ist was komisch. }
die normale lösung wäre
template<typename T,int size> auto findElemAndIKnowItsExistent(T (&arr)[size],T const& toFind){ for(int i=0;i<size;++i) if(arr[i]==toFind) return &arr[i]; return *(T*)0;//only to make the compiler happy }
Heyhey, diese "normale" Lösung kann doch unmöglich der tolle C++ Stil sein. Und du willst doch nicht zu einer MS-Erweiterung raten, oder? Da würde ich doch lieber eine Exception werfen, das macht den Compiler genauso glücklich, auch in Sprachen, die keine affigen Funktionen erlauben.
-
Optimizer schrieb:
Heyhey, diese "normale" Lösung kann doch unmöglich der tolle C++ Stil sein.
doch. der kommentar "only to make the compiler happy" muß aber zwingend dabei stehen.
Und du willst doch nicht zu einer MS-Erweiterung raten, oder?
doch. wir müssen gute compilerbauer auch belohnen, die hilfreiche erweiterungen anbieten. und nicht immer nur standard-c++ benutzen. sonst haben die compilerbauer überhaupt keinen zug, hilfreiche features einzubauen.
Da würde ich doch lieber eine Exception werfen, das macht den Compiler genauso glücklich,
aber bläht den code auf wie ungeheuer. exceptions sind hier sicherlich die zweitschlechteste lösung (nich schlechter wäre nur exit(1);.
auch in Sprachen, die keine affigen Funktionen erlauben.
dort sind exceptions angesagt, daran zweifle ich gar nicht. aber ich weiß, daß sie in c++ hier müll wären.
was stört dich eigentlich an der default-lösung?
-
Naja, unter der Annahme, dass der Programmierer (oder ein anderer) ein Mensch ist und einen Fehler einbauen könnte, der dazu führt, dass die Funktion doch nichts findet, kann die default-Lösung den Fehler enorm verschleiern. Wenn du den zurückgegebenen Pointer nicht sofort benutzt sondern in einem Tree ablegst, den du noch mit 80 weiteren Pointern füllst (und du weißt natürlich ganz genau, dass da niiiiieeeee ein 0-Pointer drin ist) und irgendwann mal eine access violation kriegst, dann hast du Spaß beim Suchen. Fail-fast ist diese Lösung jedenfalls nicht.
-
Optimizer schrieb:
Naja, unter der Annahme, dass der Programmierer (oder ein anderer) ein Mensch ist und einen Fehler einbauen könnte, der dazu führt, dass die Funktion doch nichts findet, kann die default-Lösung den Fehler enorm verschleiern.
gement war natürlich (T*)0 und nicht (T)0, sonst paßt der untere typ ja nicht zum oberen.
wenn die funktion nix findet, wird was zurückgegeben, was eh kein sinnvolles objekt sein kann, also bei vergleichen muß keiner lögen und wenn sich jemand das objekt abguckt, fliegt ne schutzverletzung, der debugger (wenn dahinter) wirft mich in die fehlerzeile und ich geh den call-stack rauf zum fehler. 0 derefenzieren ist (wenigstens mit dem MSVC60) genausogut wie assert.
aber ich würde da assert(false); hinschreiben, auch um nochmal bescheid zu sagen, daß der rechner gar nicht an diese stelle laufen darf. hatte ich schon erwähnt, daß mein ASSERT-makro auch __assume benutzt? bei mir reicht ASSERT(false) schon und __assume muß ich gar nicht mehr machen.Wenn du den zurückgegebenen Pointer nicht sofort benutzt sondern in einem Tree ablegst, den du noch mit 80 weiteren Pointern füllst (und du weißt natürlich ganz genau, dass da niiiiieeeee ein 0-Pointer drin ist) und irgendwann mal eine access violation kriegst, dann hast du Spaß beim Suchen.
würde auch nicht so lange dauern, ich würde ja gleich sehen, daß im tree ne 0 steht und dann halt zugucken, was in den tree gesteckt wird.
Fail-fast ist diese Lösung jedenfalls nicht.
ich überlasse es dem leser zur übung, kleine details fein auszuschmücken.
-
wir kommen vom thema ab.
also nur, damit das nochmal klar ist: python ist müll für dumme masochisten.
-
würde auch nicht so lange dauern, ich würde ja gleich sehen, daß im tree ne 0 steht und dann halt zugucken, was in den tree gesteckt wird.
Warum baust du dann nen ranged-checked Iterator? Wird doch auch nicht so lange dauern, wenn es irgendwann kracht, dann wirst du dir den Iterator anschaun, sehen, dass der ungültig ist, dann suchst du dir die Stellen, wo du ihn überall erhöhst und denkst nach, was es ist. Ich finde es immer angenehmer, wenn ein Programm früher abstürzt als später. Am liebsten ist es mir, wenn ich es schon gar nicht starten kann, so lange ein Fehler drin ist.
hatte ich schon erwähnt, daß mein ASSERT-makro auch __assume benutzt? bei mir reicht ASSERT(false) schon und __assume muß ich gar nicht mehr machen.
Wie implementierst du dann ASSERT auf nicht MS-Compilern? Der Unterschied ist nicht unwesentlich, wenn __assume dem Compiler bescheid sagt, dass der Kontrollfluss hier endet und was anderes das nicht tut.
volkard schrieb:
wir kommen vom thema ab.
also nur, damit das nochmal klar ist: python ist müll für dumme masochisten.Davon ging ich sowieso schon die ganze Zeit aus.
-
Optimizer schrieb:
Warum baust du dann nen ranged-checked Iterator? Wird doch auch nicht so lange dauern, wenn es irgendwann kracht, dann wirst du dir den Iterator anschaun, sehen, dass der ungültig ist, dann suchst du dir die Stellen, wo du ihn überall erhöhst und denkst nach, was es ist.
0 ist was ganz anderes, als eins hinter dem array-ende!
zugriff auf 0 wirkt bei ner guten ide wie assert.
array-ende kann nicht gefunden werden.
feines beispiel: http://www.volkard.de/vcppkold/shell_sort.html
hab erst ein dreiviertel jahr später bemerkt, daß das abtürzt.Ich finde es immer angenehmer, wenn ein Programm früher abstürzt als später. Am liebsten ist es mir, wenn ich es schon gar nicht starten kann, so lange ein Fehler drin ist.
auch deswegen mag ich c++.
Wie implementierst du dann ASSERT auf nicht MS-Compilern? Der Unterschied ist nicht unwesentlich, wenn __assume dem Compiler bescheid sagt, dass der Kontrollfluss hier endet und was anderes das nicht tut.
der unterschied ist gewaltig. wenn der rechner fälschlicherweise über ein __assume(false) läuft, dann passieren spannende, lustige und überraschende dinge. zum beispiel hat die funktion hinten gar kein ret mehr stehen, weil da eh keiner hinlaufen kann. also muß man assume sinnvollerweise auch gleich mit assert schützen.
//für ms __declspec(noreturn) void raiseAssertError(char const* cond,char const* file,int line); #ifndef NDEBUG #define ASSERT(cond) if(cond);else ::raiseAssertError(#cond,__FILE__,__LINE__) #else #define ASSERT(cond) _assume(cond) #endif
//für gcc void raiseAssertError(char const* cond,char const* file,int line) __attribute((noreturn)); #ifndef NDEBUG #define ASSERT(cond) if(cond);else ::raiseAssertError(#cond,__FILE__,__LINE__) #else #define ASSERT(cond) typedef int VHassert #endif
-
volkard schrieb:
Optimizer schrieb:
Warum baust du dann nen ranged-checked Iterator? Wird doch auch nicht so lange dauern, wenn es irgendwann kracht, dann wirst du dir den Iterator anschaun, sehen, dass der ungültig ist, dann suchst du dir die Stellen, wo du ihn überall erhöhst und denkst nach, was es ist.
0 ist was ganz anderes, als eins hinter dem array-ende!
zugriff auf 0 wirkt bei ner guten ide wie assert.
array-ende kann nicht gefunden werden.Das ist klar, aber nicht exakt das, was ich meinte. Du magst C++, weil du es für fail-fast hältst, da habe ich zwar eine andere Meinung von, aber auch das müssen wir ja nicht genauer ausführen. Den meisten Einfluss darauf, ob dein Programm schnell abstürzt, hat dein Programmcode selber und nicht die Sprache. Bei 0 ist es weg, das weiß ich, aber da kann es schon lange zu spät sein. Wie bereits aufgeführt, kann der Pointer erstmal reihum gehen und in einer Datenstruktur 10 Jahre gammeln, bis er benutzt wird und dann ist nichts mehr mit dem call stack runtergehen und schauen, ab wann es zum ersten mal nicht mehr passt.
Du würdest dann schaun, wo du die 0 in den Tree tust, das würde ich auch. Wenn du aber Pech hast, passiert das erst beim nächsten Vollmond wieder, dass das Element nicht gefunden wurde und 0 in den Tree kommt, dann hast du deine Chance verpasst und Schuld daran ist das zurückgeben eines Fluchtwerts in einer Situation, wo es IMHO krachen sollte.
-
volkard schrieb:
wir kommen vom thema ab.
also nur, damit das nochmal klar ist: python ist müll für dumme masochisten.Python ist in der Summer aller ihrer Eigenschaften für nicht-resourcenkritische Anwendungen die beste verfügbare Programmiersprache. Mit Abstand.
Wer von zwei Programmierern, einem C++-Programmierer und einem Python-Programmierer
der größere Masochist ist, da habe ich allerdings eine *ganz* andere Meinung als Du, was daran liegen mag, daß ich beides kenne. Das werde ich aber in diesem
C++-Forum nicht weiter verexplizierenPython, mein lieber volkard, ist kein "Müll", sondern eine überaus
elegente und mächtige Programmiersprache.Du bist ohnehin nur neidisch, weil ich jetzt ein freies Wochenende habe, wo
ich mit C++ noch manche Nächte bis in die Morgendämmerung durcharbeiten mußte
und auch keine müdigkeitsbedingten "C++-Ringe" mehr unter den Augen habe, seit
die Arbeit einer Woche nun mit Python an einem Vormittag zu schaffen ist.Wie dem auch sei -- von mir aus kannst Du Deine Programme in Oktalcode
einhacken.Grüße und ein schönes Wochenende allerseits
-
Ich gratuliere dir, anscheinend hast du deine Sprache gefunden.
-
Was bei mir persönlich Kopfweh auslöst sind solche Sachen:
def foo(value): if (value==1): return 123; else: return list = ["1", "2", "3"] x = foo(1) #Und was jetzt???
Das gefällt mir irgendwie gar nicht. Logisch, wer so programmiert gehört geschlagen, und das Beispiel ist nicht direkt praxisnah, aber ich hab ähnliches bei einem Bekannten schon gesehen.
-
O'Rakl schrieb:
Wer von zwei Programmierern, einem C++-Programmierer und einem Python-Programmierer
der größere Masochist ist, da habe ich allerdings eine *ganz* andere Meinung als Du, was daran liegen mag, daß ich beides kenne.Beweise?
Optimizer schrieb:
Ich gratuliere dir, anscheinend hast du deine Sprache gefunden.
Zu dumm, dass er nicht lesen kann.
-
O'Rakl schrieb:
Python, mein lieber volkard, ist kein "Müll", sondern eine überaus elegente und mächtige Programmiersprache.
da habe ich allerdings eine *ganz* andere Meinung als Du, was daran liegen mag, daß ich beides kenne. Das werde ich aber in diesem C++-Forum nicht weiter verexplizieren
-
volkard, ich hoffe, dass du durch solche Diskussionen keine wertvolle Zeit verschwendest, die eigentlich deiner VLib zu gut kommen sollte.
mfg
-
*gute
-
Volkard schrieb:
python ist müll für dumme masochisten.
Wenn man da an der richtigen Stelle nen Komma setzt, bekommt der Satz ne ganz andere Bedeutung, wer sagt uns, dass Volkard da nicht nur nen Komma vergessen hat
-
wer sagt uns, dass Volkard da nicht nur nen Komma vergessen hat
Ganz einfach, es steht nicht da und trotzdem kann ich den Satz parsen. Also muss ich den Sinn annehmen, den der Satz so vermittelt. Stell' dir vor, dein Compiler würde so rumraten wie du...
-
User--- schrieb:
Volkard schrieb:
python ist müll für dumme masochisten.
Wenn man da an der richtigen Stelle nen Komma setzt, bekommt der Satz ne ganz andere Bedeutung, wer sagt uns, dass Volkard da nicht nur nen Komma vergessen hat
na, das probiere ich gleich mal aus.
python, ist müll für dumme masochisten.
also der herr python wird angesprochen un befragt, ob müll für dumme masochisten sei. müßte aber ein fragezeichen ans ende.
falsch.python ist, müll für dumme masochisten.
also python existiert und ich fprdere müll für dumme masochisten. müßte aber ein rufzeichen nach der forderung stehen.
falsch.python ist müll, für dumme masochisten.
falsch.python ist müll für, dumme masochisten.
falsch.python ist müll für dumme, masochisten.
also das hier meinste?