C++ Gurus
-
finix schrieb:
Jester schrieb:
...
KeyType und ValueType und sind keine Typen, sie stehen für Typen.
Macht es einen Unterschied? Nein. Trägt dein Kommentar dazu bei, die Diskussion weiterzuführen? Nein. Wieso zum Geier machst du es dann?
-
finix schrieb:
KeyType und ValueType und sind keine Typen, sie stehen für Typen.
das ist unfug.
KeyType und ValueType sind typen.
"KeyType" und "ValueType" stehen für typen.
namen wie "KeyType" werden in der deutschen sprache ausgewertet zum objekt, das sie benamsen. willste den namen selbst benutzen, mußte schon quoten."finix" hat vorne ein 'f'.
finix hat aber vorne eine nase.
-
irgendwie fühlt sich das aber nicht gut an, wenn man nicht Type benutzt
-
selbst hume sikkins benutzt meistens nur einzelne buchstaben für template-parameter
template <class H, class E> struct MemFunInvoker { // restores the type of h and e then dispatches the event to the // appropriate member funtion. static void invoke(const Handler& h, const void* e) { event::CallTraits<H, E>::handle(*static_cast<H*>(const_cast<void*>(h.obj_)), *static_cast<const E*>(e)); } static void invokeConst(const Handler& h, const void* e) { event::CallTraits<H, E>::handleConst(*static_cast<const H*>(h.obj_), *static_cast<const E*>(e)); } }; template <class Fun, class E> struct FunInvoker { static void invoke(const Handler& h, const void* e) { reinterpret_cast<Fun>(h.fun_)(*static_cast<const E*>(e)); } };
-
wtf???? schrieb:
selbst hume sikkins benutzt meistens nur einzelne buchstaben für template-parameter
Und mir sagt H und E hier garnichts.
Aber ich sagte ja: diese kurzen Bezeichner sind so gaengig geworden und das ich genau das nicht verstehe. Ich habe sie ja selber lange genug verwendet
-
@wtf????
Ich habe den Thread nicht verfolgt, aber falls der Topic-Titel programm sein sollte, dann macht es herzlich wenig Sinn Code von mir als Pro- oder Contra-Argument zu verwenden.
Da ich die Voraussetzung nicht erfülle, ist jede Schlussfolgerung uninteressant.Und mir sagt H und E hier garnichts.
Was sicher ein wenig daran liegt, dass der Code aus dem Kontext gerissen ist.
Betrachtet man den Code in dem Kontext in dem er steht, dann erfordert es keinen Doktortitel um zu erkennen, dass H für Handler und E für Event steht. Desweiteren sollte man vielleicht berücksichtigen, dass der Code ein Implementationsdetail aus einem detail-Namespace ist, also nicht für den allgemeinen Gebrauch gedacht ist.Bei öffentlichen Klassen benenne ich normalerweise entweder die Template-Parameter sinnvoll oder aber erzeuge zumindest ein hübsches typedef innerhalb der Definition. Leiger bin ich diesbezüglich oft aber auch etwas nachlässig.
Schlimmer finde ich es allerdings, wenn die Semantik des Templateparmeters nicht beschrieben ist (welche Eigenschaften muss ein konkretes Argument erfüllen).
-
es geht nicht mehr um gurus
-
HumeSikkins schrieb:
Was sicher ein wenig daran liegt, dass der Code aus dem Kontext gerissen ist.
Klar, nur sehe ich halt den dennoch keinen Vorteil in einem H wenn man es auch Handle nennen kann... Und genau das habe ich gesagt: "ich verstehe es nicht". Wobei ich es auch lange so gemacht habe, aber wie ich mal darueber nachgedacht habe, habe ich festgestellt, dass es nur Bequemlichkeit ist.
-
verstehe die einstellung von HumeSikkins nicht. man sollte doch überall gut programmieren (wenn man es kann) und nicht nur nach aussen hin.
-
rasta schrieb:
verstehe die einstellung von HumeSikkins nicht. man sollte doch überall gut programmieren (wenn man es kann) und nicht nur nach aussen hin.
ja.
aber nach innen gut und nach außen gut könne zweierlei dinge sein.
ich stelle mir vor, ich mache gerade mit containern rum. mit hashtables mal. dann mit avl-trees. dann mit tries, dann mit ...
alles auf der suche nach der geilsten datenstruktur, um ein gutes dictionary voller strings, wie sie in hochbelasteten nameservern so rumliegen, zu finen.da die gante zeit Key statt K und Value statt V zu schreiben, würde einen töen. wohlgemerkt, für eine dieser datenstrukturen, wenn sie zufriedenstellend sein soll, brauche ich mindestens 4 wochen.
nun kann man sich auf den standpunkt stellen, daß man immer Key,Value schreiben sollte. den standpunkt halte ich für irrig.
nun kann man sich auf den Standpunkt stellen, man sollte nach abschluß der forschungen K,V durch Key,Value ersetzen. geht ja mit search&replace der jeweiligen entwicklungsumgebung sehr gut. den standpunkt hielt ich für befremdlich. denn immerhin war *ich* ja nach solchen monaten sowas von im geschäft, daß ich mit den einbuchstabern weniger probleme hatte als mit langen bezeichnern.
nun kann man sich auf den standpunkt stellen, man solle K,V lassen. (oder H,E). das habe ich bisher so gemacht. und es war nie ein problem. aber humes code zu lesen war erweckend. ich hab ja nix auf anhieb gerafft (klar, nach 30 sekunden tröpfelt die erleuchtug ein, aber warum 30 sec dumm sein?). nun habe ich zu berfüchten, daß er meinen K,V-code genausoschlecht liest wie ich seinen H,E-code.
ich schau mal. bin gerade heftig auf einem lokalen c++-vereinfachungs-kreuzzug und da fliegen auch ein paar templates und ein wenig metaprogrammierung vorbei. ich schau mal, wo ich einbuchstaber duldbar finde.
übrigens waren zu anfang der template-benutzung einbuchstaber optimale bezeichner. man hatte ja nur mal T oder ganz selten noch nen zweiten buchstaben. da galt ungefär sowas
erster buchstabe klein erstes wort ein verb im infinitiv ist eine funktion, die bool liefert erstes word ein verb in befehlsform ist eine funktion erstes wort ein nomen ist variable erstes wort gross [b] erstes wort einbuchstaber ist typ als templateparemater[/b] alle anderen buchstaben gross ist makro sonst ist klasse
-
aber humes code zu lesen war erweckend. ich hab ja nix auf anhieb gerafft
Und lag das wirklich an so Kleinigkeiten wie H und E oder vielmehr daran, dass der Code insgesamt nicht sonderlich klar ist und einige Basiskonzepte einfach schrecklich schlechte Namen haben?
Ich hätte getippt, dass deine Schwierigkeiten an drei Dingen liegen:
1. Der Code ist komplex, weil die Domäne komplex ist. Überlappende Events, verwaiste Handler usw. Da kommen viele Randfälle zusammen.
2. Der Code ist komplex, da er bereits optimiert ist. Die "triviale" Implementation wäre deutlich einfacher, erzeugst dafür aber auch deutlich mehr Code (virtual function bloat -> type erasure).
3. Der Code ist komplex, da einige Konzepte nicht gut benannt und nicht optimal orthogonal sind.
Der dritte Punkt liegt eindeutig in meiner Unfähigkeit und Unerfahrenheit. Die relativ ausfürhliche Dokumentation (sowie die Tests) war dazu gedacht, über dieses Problem hinweg zu helfen.
Alles in Allem denke ich, dass man den Code sicher noch etwas klarer machen kann. Ein Wunder würde ich allerdings selbst von Volkard oder Shade oder anderen Gurus nicht erwaten. Warum? Ähnliche Implementationen von
anerkannten C++ Experten sind imo nicht wirklich weniger komplex (zum Vergleich schaue man sich boost::signal oder aber Alexandrescus policy based observer an. Letztere ist in den zwei CUJ-Kolumnen
"A policy based observer" beschrieben).PS: Falls jemand eine bessere Version hat, immer her damit.
Muss aber die Anforderungen die ich beschrieben habe erfüllen. Also z.B. Typesafe und schneller als boost::signal sein.
-
nun habe ich zu berfüchten, daß er meinen K,V-code genausoschlecht liest wie ich seinen H,E-code.
Ich habe von dir eine Version deiner Volkard-Lib. Da gibt es einige Sachen die ich nicht auf Anhieb verstehe. Das liegt aber weniger an den Namen in der Implementation oder an den verwendeten Sprachmitteln sondern vielmehr an der Theorie. Da muss ich mich halt mal eine Stunde hinsetzen, an meine Informatik-Ausbildung zurückdenken, ein- zwei Seiten im Sedgewick nochmal wiederholen und dann geht's auch.
@Shade
Klar, nur sehe ich halt den dennoch keinen Vorteil in einem H wenn man es auch Handle nennen kann
Handle kann ich es z.B. nicht einfach nennen. Der VC 6.0 (der Compiler mit dem ich arbeite) hat die herrliche Angewohnheit zu sterben, wenn er über einen Template-Parameter stolpert, der den selben Namen wie eine normale Klasse hat.
Und wenn ich die Wahl habe versaue ich mir lieber meine Template-Parameter als meine Klassen. Eine Klasse E wäre sicher schlimmer als ein Template-Parameter E.
Bevor du jetzt antwortest: Natürlich ist das keine gültige Ausrede, da man den Parameter ja auch HandlerType oder DerTypDerDaWoSpaeterDurchEinHandlerErsetztWird nennen kann
-
HumeSikkins schrieb:
aber humes code zu lesen war erweckend. ich hab ja nix auf anhieb gerafft
Und lag das wirklich an so Kleinigkeiten wie H und E oder vielmehr daran, dass der Code insgesamt nicht sonderlich klar ist und einige Basiskonzepte einfach schrecklich schlechte Namen haben?
ich hab nur das gepostete fragment angeschaut. dort sagten mir E und H erstmal wenig. recht schnell habe ich dann gerafft, daß E wohl Event und H wohl Handler heißen.
HumeSikkins schrieb:
Ich hätte getippt, dass deine Schwierigkeiten an drei Dingen liegen:
1. Der Code ist komplex, weil die Domäne komplex ist. Überlappende Events, verwaiste Handler usw. Da kommen viele Randfälle zusammen.kann sein. domäne ist mir unbekannt.
HumeSikkins schrieb:
2. Der Code ist komplex, da er bereits optimiert ist. Die "triviale" Implementation wäre deutlich einfacher, erzeugst dafür aber auch deutlich mehr Code (virtual function bloat -> type erasure).
jein. mit direktem code würde ich vielleicht das komzept eher sehen, mich dafür aber genausolange über ineffizienz wundern, wie ich vorher an überlegungszeit gespart habe. (also bei dir würde ich mich so lange wundern, weil ich von dir auch nur optimalen code zu sehen erwarte.)
3. Der Code ist komplex, da einige Konzepte nicht gut benannt und nicht optimal orthogonal sind.
das geht uns allen so. Shades angesprochene 30% der zeit, die er für's namensuchen verbraucht, sind wenig. für die benamsung brauche ich auch meistens nicht mehr. aber für die orthogonalität (und noch ein paar nettigkeiten) gehen zur zeit 99% drauf, seit monaten.
Der dritte Punkt liegt eindeutig in meiner Unfähigkeit und Unerfahrenheit.
in deiner domäne biste sicherlich erfahrener als alle hier. aber vielleicht mußte mal irgendwas praktisches wie einen guten http-server bauen, damit du objektiv erfahren bist (ok, dauert lange, aber es könnte den aufwand wert sein, insbesondere, um nicht dauerhaft in völlig irrelevantes abzuglitschen, manchmal frage ich mich nämlich, weshalb das fünfhundertachtunddreißigste entwurfsmuster implentiert und mit grußem bahnhof begrüßt wird, aber ich keinen kenne, der das benutzen mag, außer für eine demo).
Alles in Allem denke ich, dass man den Code sicher noch etwas klarer machen kann. Ein Wunder würde ich allerdings selbst von Volkard oder Shade oder anderen Gurus nicht erwaten.
ich weiß nicht, was Schade macht. aber ich bin an ganz anderen problemen dran. mein projekt ist zur zeit "ich habe eine kernel.h und eine kernel.cpp, die mir triviale und elemetare sachen wie write() oder becomeIdleThread() zur verfügung stellen (so wenig wie möglich natürlich). und ich baue alles darauf auf, ich inkludiere außer in kernel.cpp keinen header mit <> drumherum. und ich achte auf einfachheit und kürze als ganz allerwichtigstes. zum beispiel habe ich das doofe problem gelöst, daß man nicht einen vector oder ein array mit 1000 ostreams anlegen kann. aber ich brauche das, also mache ich es. mit einem ArrayAllocator (der zählt einfach hoch) und placement new (op new(size_t,ArrayAllocator&). kennst ja meine abneigung gegen default-konstruktoren. jetzt darf ich sie ausleben. :D. naja, ich habe keine ahnung, ob der kram am ende gut wird. ich muss annehmen, dass die großen gurus meine allüren als kinderkrankheiten abgelegt haben. ist mir aber egal. ich will {for each (i,meincontainer) tuwas(*i);} schreiben und seit heute schreibe ich es. solche versuche hab ich öfters gemacht, fast jährlich, aber so weit, wie heute, bin ich nie auch nur ansatzweise gekommen."
-
HumeSikkins schrieb:
Ich habe von dir eine Version deiner Volkard-Lib.
oh, gibt es sowas noch?
schick sie mir mal volkard@normannia.deHumeSikkins schrieb:
Und wenn ich die Wahl habe versaue ich mir lieber meine Template-Parameter als meine Klassen. Eine Klasse E wäre sicher schlimmer als ein Template-Parameter E.
ich benutze gerade eine IDE (Code::Blocks), die auch bei template-paramtern so ein hilfe-fensterchen aufmacht und die möglichkeiten anzeigt.
also ich tippe
foo<
und er schreibt
foo<U,K,Y>
haha.
ist natürlich egal, weil ich foo kenne und selber gebaut habe oder das handbuch vorher gut gelesen habe, aber naja, vielleicht sollten wir in zukunft den template-parametern die gleiche achtung zollen wie normalen parametern.
-
HumeSikkins schrieb:
Alles in Allem denke ich, dass man den Code sicher noch etwas klarer machen kann. Ein Wunder würde ich allerdings selbst von Volkard oder Shade oder anderen Gurus nicht erwaten. Warum? Ähnliche Implementationen von
anerkannten C++ Experten sind imo nicht wirklich weniger komplexHabe ich auch nie behauptet dass es unklar ist oder klarer geht. (btw, Guru bin ich auch nicht, ich schaue immer noch zu dir und volkard auf).
Was mich aber beim ersten Blick verwirrt hat war ein H und ein Handler. Dass H fuer Handle oder Handler steht, ist in dem Zusammenhang genauso klar wie das E Event. Liegt aber wohl hauptsaechlich daran, dass Handler unguenstig gewaehlt wurde. Denn, soweit ich dass sehe, ist es nicht viel mehr als eine Verwaltung von Objekt und Methode. Und Handler ist gar sehr allgemein...
Und da spiesst es sich IMHO. Du hast 2 Typen die Handler/Handle heissen... Das hat jetzt weniger mit dem H zu tun.
PS: Falls jemand eine bessere Version hat, immer her damit.
Muss aber die Anforderungen die ich beschrieben habe erfüllen. Also z.B. Typesafe und schneller als boost::signal sein.Der Code sieht IMHO ganz gut aus, die casts sind natuerlich ein Krampf, aber viel anders wird es nicht gehen...
@volkard:
taugt Code::Blocks denn mittlerweile etwas?
-
Ich möchte die Frage präzisieren. Beherrscht es einfaches Refactoring wie etwas umzubenennen oder Funktion extrahieren? Ich habe bisher noch keine IDE für C++ gesehen, die das kann.
volkard schrieb:
ich will {for each (i,meincontainer) tuwas(*i);} schreiben und seit heute schreibe ich es.
Ui, das will ich auch. Das heißt, ich tue es, aber leider nicht, wenn ich was mit C++ mache.
Was hast du dir da feines zusammengehackt?
-
Shade Of Mine schrieb:
taugt Code::Blocks denn mittlerweile etwas?
ich hab den debugger noch nicht ausprobiert (spricht für mich, oder?). und das hinzufügen von files ist einen oder zwei klicks zu umständlich. und ich hab nur console-anwendungen gebaut. sonst sind mir keine nachteile aufgefallen. aber einen riesigen vorteil hat sie: ich kann mein usiversal makefile drunter haben und Code::Blocks ruft einfach mein makefile auf.
das universal makefile mußte übrigens zerstört und wiederaufgebaut werden# Volkards universal makefile # (c) 1999-2005 volkard@normannia.de # feel free to use it in any ways. CXXFLAGS:=-Wall -Werror -march=i586 -O3 -fno-rtti -pipe -s -DNDEBUG -DUNITTEST #CXXFLAGS:=-Wall -Werror -march=i586 -O3 -fno-rtti -pipe -s -DNDEBUG PROJECT:=$(basename $(notdir $(CURDIR))) TARGET_EXT:= ifeq ($(OS),Windows_NT) TARGET_EXT:=.exe endif TARGET:=$(PROJECT)$(TARGET_EXT) zip:=$(PROJECT).rar sources:=$(wildcard *.cpp) objects:=$(sources:.cpp=.o) deps:=$(sources:.cpp=.d) all: $(TARGET) .PHONY: all clean run zip $(TARGET): $(objects) $(deps) $(CXX) $(CXXFLAGS) -o $(TARGET) $(objects) -include $(deps) %.o %.d: %.cpp makefile $(CXX) $(CXXFLAGS) -MMD -c $< clean: -$(RM) $(TARGET) $(objects) $(deps) run: $(TARGET) ./$(TARGET) zip: -$(RM) $(zip) rar a -r -s -m5 -ap$(PROJECT) $(zip) *.cpp *.h makefile
das alte war zu doof, die dependencies auch immer neu zu schreiben, weil sich eine *.h geändert hat, die in einer *.d afgelistet war. es waren die *.d nur von den *.cpp abhängig, was falsch ist. jetzt werden mit -MMD immer zur gleichen zeit eine *.o und eine *.d gebaut, womit auch garantiert ist, daß die *.d immer akltuell ist.
-
Optimizer schrieb:
volkard schrieb:
ich will {for each (i,meincontainer) tuwas(*i);} schreiben und seit heute schreibe ich es.
Ui, das will ich auch. Das heißt, ich tue es, aber leider nicht, wenn ich was mit C++ mache.
Was hast du dir da feines zusammengehackt?
das glaubste eh nicht, so einfach isses.
ich hab übrigens den c++-standard verlassen und benutze hemmungslos typeof und auch die steuerung des alignments.#define each2(i,a) (typeof((a).begin()) i=(a).begin(),VHend=(a).end();i!=VHend;++i) //für for each(i,myVector) #define each3(i,a,b) (typeof(a) i=a,VHend=b;i!=VHend;++i) //für for each(i,0,100)
ich muß leider each2 und each3 nehmen, weil ich keine möglichleit sah, für den MS-compiler beides eache heißen zu lassen (auf gcc kann ichs mit variadic macros.).
-
Optimizer schrieb:
Ich möchte die Frage präzisieren. Beherrscht es einfaches Refactoring wie etwas umzubenennen oder Funktion extrahieren?
äh. umbennenen macht man mit search&replace, oder? naja, man nennt es einfach um und fragt den compiler, wo's vorkommt, und macht die fehler alle raus. bin nir drauf gekommen, daß die ide das können sollte. auf jeden fall kann Code::Blocks sowas nicht. Code::Blocks ist eindeutig sparsam mit features (hoofentlich bleibt das auch so).
und was heiß es, eine funktion zu extrahieren?
-
Aso, dann arbeitest du aber immer noch mit dem Iterator. Ein nettes Spielzeug ist es, aber an die Eleganz von
List<int> foo = new List<int>(); foreach( int x in foo ) sum += x;
kommt es so noch nicht ran. Es müsste doch möglich sein, in dem Makro den Iterator gleich zu dereferenzieren und einer Referenz auf das aktuelle Objekt den Namen zu geben, den man als Parameter angibt, oder?