Verleitet die Mächtigkeit der Sprache C++ dazu es kompliziert zu machen?
-
Oberflächlich könnte man denken ja, aber Overengineering (wenn es das denn ist, oder Spieltrieb) kann man (und tut man) auch in anderen Sprachen ausleben. Vielleicht ist es umgekehrt so, dass C++ Leute, die es gerne kompliziert lieben, anzieht.
-
Meiner Erfahrung nach ist es genau umgekehrt: Die Mächtigkeit von C++ erlaubt es mir, viele Dinge einfacher zu lösen als in anderen Sprachen...
-
mMn. ist das, was in C++ als idiomatisch gilt, ziemlich komplex.
C++ lässt sich eben auf 100000 Arten programmieren und für jeden Fall gibt es mehrere beste Wege und tausend schlechte Wege.In Java rattert man Design-Patterns runter und gut.
-
std library und boost verleiten zum komplizierten
-
Viele Sachen kann man mit den sprachlichen Mitteln viel einfacher ausdruecken als in anderen Sprachen, aber es passiert mir schon oefters, dass ich etwas von vornherein generisch mache, wenn es ueberhaupt nicht noetig ist und es nur eine Instanziierung ueberhaupt gibt und ich mich dann mit schwierigen Template-ausdruecken und fuerchterlichen Fehlermeldungen herumschlagen darf.
-
Es kommt auf die Probleme an, die man lösen will. Z.B. habe ich wegen RAII in C++ weniger Fehlerquellen, als z.B. in Java (mit dem ich täglich zu tun habe).
Dann gibt es aber Probleme, die ich in Java einfacher lösen kann, und es trotzdem funktioniert.Als ich damals von TMP erfahren hatte, versuchte ich krampfhaft TMP einzusetzen oder zumindest Probleme dafür zu finden. Das ist natürlich total bekloppt. Weil es mich nicht weiter gebracht hatte.
Disziplin ist es nicht, die man braucht. Man braucht sehr viel Selbstbewusstsein und Ar*** in der Hose, um drüber zu stehen, das man halt etwas in C++ einfach einfach gelöst hat.
-
volkard schrieb:
Vermutlich meinste
http://www.ariel.com.au/jokes/The_Evolution_of_a_Programmer.htmlDas ist Köstlich.
Ja in der Richtung "overengineered" könnte man das auch betrachten.
-
Ich finde dass SFML ein gutes Beispiel für schönes C++ ist. Klar und sauber.
-
Ich denke vor allem TMP und Boost verleiten Neulinge zum overengineering.
-
std__boost schrieb:
std library und boost verleiten zum komplizierten
Dieser Post ist nicht ausser Acht zu lassen. Statt einer einfachen
for
-Schleife tendiert man zustd::generate
und irgendeinem lokalen Funktor oder einem Lambda. Lesbarer oder "besser" finde ich das nicht. Wobei ich gestehen muss, dass ich als Hobby-Programmierer auch dazu tendiere, kleine Dinge fürchterlich zu overengineeren. Zumindest macht es Spass.
-
asfdlol schrieb:
std__boost schrieb:
std library und boost verleiten zum komplizierten
Dieser Post ist nicht ausser Acht zu lassen. Statt einer einfachen
for
-Schleife tendiert man zustd::generate
und irgendeinem lokalen Funktor oder einem Lambda. Lesbarer oder "besser" finde ich das nicht."Effective STL" ist ein Buch, wo der Autor einem Seite um Seite einhämmert, daß man ja keine einfachen Schleifen mehr benutzen darf.
-
Tyrdal schrieb:
Ich denke vor allem TMP und Boost verleiten Neulinge zum overengineering.
Das liegt aber eher am Neuling als an Boost.
Boost selber ist "over-engineered", damit man das als Benutzer von Boost nicht machen muss.
asfdlol schrieb:
std__boost schrieb:
std library und boost verleiten zum komplizierten
Dieser Post ist nicht ausser Acht zu lassen. Statt einer einfachen
for
-Schleife tendiert man zustd::generate
und irgendeinem lokalen Funktor oder einem Lambda. Lesbarer oder "besser" finde ich das nichtIch sehe das ganz anders. Statt einem komplizierten
for
-Statement tendiere ich zu fertigen Algorithmen wiegenerate
. Beifind
,remove
undpartition
ist der Vorteil offensichtlicher.
-
TyRoXx schrieb:
Bei
find
,remove
undpartition
ist der Vorteil offensichtlicher.Bei find will man üblicherweise die Findeposition weiterverarbeiten, da bietet sich eine Funktion an. Die hat nen guten Zweck und nen passenden Namen. remove und partition auch. generate ist schon gelegentlich fraglich.
Bevozugst Du auch die Ausgabe als copy auf ostream-Iteratoren?
-
TyRoXx schrieb:
Tyrdal schrieb:
Ich denke vor allem TMP und Boost verleiten Neulinge zum overengineering.
Das liegt aber eher am Neuling als an Boost.
Tja der Neuling denkt halt das muss so und das ist meist nicht der Fall.
-
Worin liegt bei dieser Frage das Problem?
Mit Ausnahme von ASSEMBLER und vielleicht noch des alten BASIC ist jede
Programmiersprache in ihren Möglichkeiten komplex. Solange man nicht alles
voll versteht oder braucht, benutzt man es nicht. Oder anders gesagt, man
verwendet die komplexeren Dinge erst dann, wenn man darin einen Vorteil sieht.Als Führerscheinneuling setze ich mich auch nicht gleich in einen Formel1-Rennwagen!
-
volkard schrieb:
Bevozugst Du auch die Ausgabe als copy auf ostream-Iteratoren?
Ich verwende zwar möglichst selten
ostream
. Aber wenn ich das mache, dann gerne mit Iteratoren.Verwirrte Anfänger gibt es immer.
Die Mächtigkeit von C++14 verleitet mich persönlich dazu es richtig zu machen ("braucht man die Indirektion hier wirklich?"). Ich glaube, dass ich inzwischen einschätzen kann, wann das zu kompliziert wird.
In anderen Sprachen, zum Beispiel C#, mache ich mir viel weniger Gedanken über Kleinkram. C# bietet weniger Spielraum für "clevere" Lösungen. Man braucht die auch nicht, weil sowieso alles ineffizient ist.
-
berniebutt schrieb:
Worin liegt bei dieser Frage das Problem?
Solange man nicht alles voll versteht oder braucht, benutzt man es nicht. Oder anders gesagt, man verwendet die komplexeren Dinge erst dann, wenn man darin einen Vorteil sieht.
Das Problem ist, dass man Vorteile sieht, die gar nicht da sind. Z.B. hat man eine Funktion und anstatt sie einfach so zu schreiben, bietet man sie fuer integer und float an, wobei man jeweils mit enable_if und is_integral und so dafuer sorgt, dass die richtige Ueberladung getroffen wird. Man schlaegt sich dann mit templates und unverstaendlichen Fehlermeldungen herum und schliesslich hat man eine wundervolle generische Funktion mit Sicherheitschecks und allem, nur um am Ende festzustellen, dass man dafuer eine Stunde Arbeit gebraucht hat und ein einfacher Overload fuer double und int voellig ausreicht, aber in 2 Minuten fertig gewesen waere.
-
TyRoXx schrieb:
In anderen Sprachen, zum Beispiel C#, mache ich mir viel weniger Gedanken über Kleinkram. C# bietet weniger Spielraum für "clevere" Lösungen. Man braucht die auch nicht, weil sowieso alles ineffizient ist.
Jo, geht mir auch so.
Heißt aber nicht unbedingt, daß die Programme in Java/C# dann lesbarer werden. Da passieren auf magische Weise manchmal so Dinge wie class ObjectManager, dependency inversion, tiefe Kopien mithilfe eines XML-Serielizers,
http://www.c-plusplus.net/forum/327984-full
-
volkard schrieb:
asfdlol schrieb:
std__boost schrieb:
std library und boost verleiten zum komplizierten
Dieser Post ist nicht ausser Acht zu lassen. Statt einer einfachen
for
-Schleife tendiert man zustd::generate
und irgendeinem lokalen Funktor oder einem Lambda. Lesbarer oder "besser" finde ich das nicht."Effective STL" ist ein Buch, wo der Autor einem Seite um Seite einhämmert, daß man ja keine einfachen Schleifen mehr benutzen darf.
Und womit wird das begründet?
-
Questionmark schrieb:
volkard schrieb:
"Effective STL" ist ein Buch, wo der Autor einem Seite um Seite einhämmert, daß man ja keine einfachen Schleifen mehr benutzen darf.
Und womit wird das begründet?
Die Funktionen aus
<algorithm>
sind wegabstrahierter Programmfluss.
Wenn man eine Schleife selbst schreibt, z.B. so:vector<int> result; for (int i : v) { if (i % 2 == 0) result.push_back(i); }
reicht es nicht, den Schleifenkopf zu lesen um zu verstehen, was passiert. Man muss den ganzen Schleifenkörper, der ja durchaus länger als hier sein kann, anschauen.
Wenn man allerdings Funktionen aufruft, die diese Schleifen für einen selbst intern umsetzen, erkennt man direkt, was grob passiert.
vector<int> result; copy_if(begin(v), end(v), back_inserter(result), [](int i) { return i % 2 == 0; });
Hier im Beispiel weiß ich direkt einiges, z.B. dass manche Elemente von
v
nachresult
kopiert wird, dass inresult
nachher nichts drin ist, was vorher nicht inv
war, dass die Länge vonresult
<= der Länge vonv
sein wird ...
Zusätzlich vermeidet man eventuelle Dusseligkeitsbugs wie Endlosschleifen, ungültige Iteratoren usw.Der code wird selbstdokumentierender, und man programmiert einfach auf einer höheren Abstraktionsebene.
Das kann noch weitere Vorteile haben, wie beispielsweise den, dass man irgendwann einfach seincopy_if
durch ein hypothetischescopy_if_multithread
oder sowas ersetzen kann.Klar kann es auch situationen geben, in der dieser funktionale Stil die Lesbarkeit nicht verbessert sondern verschlechtert, oder man aus anderen Gründen besser zur weniger abstrakten Lösung greift. Das muss man dann abwägen und ist auch ein Bischen Frage der persönlichen Vorlieben.
Die Syntax für sowas ist in C++ vielleicht nicht die schönste, aber mein persönlicher Default ist trotzdem auch hier dieser funktionale Stil.