Das ist das Ende von C++!
-
Zeus schrieb:
*gg* Da wiedersprichst aber einige. Unter anderem war die Motivation D zu entwickeln, weil C++ so eine grosse riesenggrosse C kompatibilät hat.
Unter D kannst du C funktionen nutzen und D-Typen sind kompatible zu C-Typen aber dabei Endes auch, so weit ich gesehen habe.Ich hab jetzt nicht gesagt dass D und C source-kompatibel sind, aber man kann alles aus C in D umsetzen, nicht kompilieren. Bevor jetzt der Präprozessor genannt wird, der lässt sich in D durch Templates und mehr Schreibarbeit umsetzen :p . Kompatibel zwischen D und C sind noch die in statische Bibliotheken exportierten Konstanten, Funktionsaufrufe und Struktur-Alignments... Aber was meinst du mit "dabei Endes auch" ?
Kompatibel sind D und C++ zwar nicht zwingend, aber größtenteils lässt sich C++ in D recht leicht übersetzen mit nur wenigen Änderungen. Ein D-Unterforum könnte bei solchen Übersetzungsproblemen helfen und bei generellen Problemen mit D. Fragen über sprachübergreifende APIs könnten ja in die anderen Foren.
-
daHa schrieb:
mixins sind da
http://www.digitalmars.com/d/mixin.html
ganz gut beschriebenconst siehe da:
http://www.digitalmars.com/d/attribute.html#constSehr hilfreich. Ohne dich hätte ich die Dokumentation wohl nie gefunden.
Btw, erstes war mir schon halbwegs klar. Es ging mir um die konkrete Anwendung, was mit anderen Sprachmitteln nicht oder nur sehr umständlich möglich wäre. Zweites ist keine Antwort auf meine Frage.
-
Simon2 schrieb:
Das Argument stärkt aber sogar die Konsistenz des templates UND des generischen Ansatzes, weil die Kopiersemantik nicht stillschweigend gebrochen und durch Referenzsemantik ersetzt wird (oder anders herum).
Aber das primitive Datentypen nicht mit Generics verwendbar sind, weil die Kopiersemantik nicht ins Konzept passt, also gebrochen werden müsste, das stört dich ... Ich denke hiermit hat sich der Widerspruchszähler auf 2 erhöht.
Simon2 schrieb:
Leider haben beide in diesem Fall nicht die Möglichkeiten dazu: Kein myClass-Programmierer kann seine Klasse so schreiben, dass sie so funktioniert wie primitive Typen und kein template-Programmierer kann sein template so entwerfen, dass sie mit primitiven Typen genauso arbeiten wie mit Klassentypen.
Ich kann schon die ganze Zeit nicht nachvollziehen, warum du überhaupt primitive Datentypen und Klassen gleich behandeln willst, aber bitte, dann reduzieren wir es auf den gemeinsamen Nenner: nichts. Was willst du denn mit primitiven Datentypen großartig anstellen? Operatoren stehen dir ja in Generics nicht zur Verfügung. Dadurch sollte eigentlich klar sein, dass deine Kritiken absolut am Ziel vorbei gehen, da sie keinerlei Praxisbezug besitzen. Ich habe dir ein Beispiel (von vielen) genannt, dass auch ganz gut ohne Gleichbehandlung von primitiven Datentypen und Klassen auskommt, aber Praxisbezug ist ja anscheinend unwesentlich. Hauptsache die Theorie ist so, wie es C++ Entwickler gewöhnt sind, ja nicht umdenken ...
Simon2 schrieb:
Dass der Klassenentwickler sich Gedanken machen muss, wie Objekte seines Typs auf verschiedene Semantiken reagieren, bedeutet nicht, dass der template-Programmierer keine Verantwortung mehr dafür hat, was seine Funktion mit den übergebenen Parametern macht, oder ?
Das "Was" stand nie in Frage, sondern das "Wie".
Simon2 schrieb:
Aber komm, lass stecken: Du hast offensichtlich schon viiiiiieeeeel templates programmiert und seeeeehr großes interesse daran, Dich damit auseinanderzusetzen.
Ich hab genau so wie die meisten anderen auch meine Erfahrung mit Templates gemacht, auch Modern C++ Design und genau so mit Boost als konkreten Anwendungsfall gearbeitet, aber nachdem ich ja auch Java programmiere, habe ich Templates anscheinend wirklich nicht verstanden.
Simon2 schrieb:
Und Java ist offensichtlich üüüüüüüüüberhaupt keine heilige Kuh von Dir !
Nein, denn ich kann von mir ja behaupten beide "Welten" zu kennen, wie sieht es da mit dir aus? ...
-
Clw schrieb:
Badestrand schrieb:
....... schrieb:
Badestrand schrieb:
Will nichts zu den zahllosen Einzeldiskussionen beitragen, aber ich wäre für ein D-Unterforum; Einfach der Vollständigkeit halber und damit man eine Anlaufstelle hat, falls man es mal ausprobieren möchte
Neue Unterforen werden erst bei Bedarf erstellt.
Ich hab Bedarf...
Ich denke der Bedarf wäre schon da
Warum gibts dann so gut wie keine Threads zum Thema D?
-
Ok. Der Thread kann geschlossen werden.
Cool
Der gewünschte Benutzername wurde vom Administrator gesperrt.
-
quote experte schrieb:
...
Ich kann schon die ganze Zeit nicht nachvollziehen, warum du überhaupt primitive Datentypen und Klassen gleich behandeln willst, ...std::vector ... um nur ein Beispiel zu nennen ...
Ich weiß, alles Schrott, den sich nur ein Durchgeknallter ausgedacht hat.Gruß,
Simon2.
-
Waerst Du zufrieden, wenn man die primitven Datentypen ganz rausnimmt?
-
groovemaster schrieb:
daHa schrieb:
mixins sind da
http://www.digitalmars.com/d/mixin.html
ganz gut beschriebenconst siehe da:
http://www.digitalmars.com/d/attribute.html#constSehr hilfreich. Ohne dich hätte ich die Dokumentation wohl nie gefunden.
Btw, erstes war mir schon halbwegs klar. Es ging mir um die konkrete Anwendung, was mit anderen Sprachmitteln nicht oder nur sehr umständlich möglich wäre. Zweites ist keine Antwort auf meine Frage.also die frage war
groovemaster schrieb:
Wie kann man eigentlich in D ein Objekt erstellen, dass nach der Initialisierung, welche laufzeitabhängig ist, nicht mehr verändert werden darf?
aus der doku:
http://www.digitalmars.com/d/attribute.html#const schrieb:
A const declaration without an initializer must be initialized in a constructor (for class fields) or in a static constructor (for static class members, or module variable declarations)
also zB
class A { this(int i){ mi = i; } const int mi; } int main(char[][] args) { //zur laufzeit const 100 A a = new A(100); //zur laufzeit const 200 A b = new A(200); return 0; }
und das mit den mixin, du kannst das ja, ebenfalls aus der doku, in anderen sprachen nachprogrammieren und dir den unterschied anschaun, die anderen bsps ebenfalls dementsprechend evaluieren
int y = 3; template Foo() { int abc() { return y; } } void test() { int y = 8; mixin Foo; // local y is picked up, not global y assert(abc() == 8); }
bezueglich einsatzgebiet, lass deine fantasie spielen
also ein bissl hilfreich sind die urls schon, weil sie beinhalten sehr wohl antworten auf deine fragen, ist aber nur meine persoenliche meinung, du musst das natuerlich nicht so sehen
-
std::vector ... um nur ein Beispiel zu nennen ...
Wäre ein gutes Beispiel, wenn es nicht etwas analoges dazu in Java geben würde, dass diese Klasse als Argument entkräftet ..
-
Die Mods stinken. Mal sehen ob die hier noch lesen oder das ganze auch schon langweilig finden.
-
quote experte schrieb:
std::vector ... um nur ein Beispiel zu nennen ...
Wäre ein gutes Beispiel, wenn es nicht etwas analoges dazu in Java geben würde, dass diese Klasse als Argument entkräftet ..
Ein gutes Beispiel für ein template mit Kopiersemantik (auch für Klassentypen) ? Da bin ich wirklich gespannt...
Übrigens: IIRC C hat dasselbe Problem ...
Gruß,
Simon2.
-
Und wieso ist dann sowas mit const nicht möglich?
int main() { int a = /*...*/; const int b = a; }
Meine Frage diesbzgl. war ja erstmal vollkommen losgelöst vom Scope. Auf der einen Seite steht da, dass mit const Konstanten zur Kompilierzeit aufgelöst werden können. Auf der anderen Seite sehe ich aber nicht, wann und wo Laufzeitkonstanten möglich sind. Deshalb war ein nichtssagender Link auf die Doku einfach nur nutzlos.
daHa schrieb:
und das mit den mixin, du kannst das ja, ebenfalls aus der doku, in anderen sprachen nachprogrammieren und dir den unterschied anschaun, die anderen bsps ebenfalls dementsprechend evaluieren
int y = 3; template Foo() { int abc() { return y; } } void test() { int y = 8; mixin Foo; // local y is picked up, not global y assert(abc() == 8); }
OK, nehmen wir einfach mal das Beispiel. Ohne Mixins schreibe ich
int y = 3; void test() { int y = 8; int abc() { return y; } assert(abc() == 8); }
Wo soll hier die Notwendigkeit von Mixins sein? OK, ich höre dich jetzt schon aufschreien und sagen, es könnte ja theoretisch auch eine weitere Funktion geben, wo ich dann anstatt einer erneuten nested Funktion einfach "mixin Foo;" schreibe. Aber vllt. merkst du ja worauf ich hinaus will. Die Beispiele zeigen zwar ungefähr wie Mixins in D funktionieren. Sie sind aber relativ sinnlos. Deshalb war meine Frage, wo hier sinnvolle Anwendungen in "Real World Applications" sind, die mit anderen Sprachmitteln nicht möglich wären. Ich sehe keine, oder zumindest nur das was Clw schon schrieb, dass man damit Code Redundanzen vermeiden kann. Es sind im Grunde ja nichts anderes als scopelose Templates. "Normale" Templates scheinen mir aber grundsätzlich eine sauberere Lösung zu sein. Du kannst mich mit einem praktischen Beispiel aber gerne vom Gegenteil überzeugen.
-
das mit dem const ist in D so wie es eben ist
entweder etwas ist const, oder nicht
darueber zu diskutieren ob const wie in c++ mehr sinn macht wuerd die naechsten 20 seiten sinnlos hin und her fabrizieren.bez mixin, reald wordl bsps hab ich keine, leider fehlt mir die zeit mich mehr als hin und wieder ein paar minuten mit D zu beschaeftigen
was mir aber als zb einfaellt waer folgendes
import std.stdio; interface IReader{ void doRead(); } //------------------------------------------------ interface IWriter{ void doWrite(); } //------------------------------------------------ template IReaderDefaultImplementation(){ void doRead(){ doOpen(); writefln("IReaderDefaultImplementation"); doClose(); } } //------------------------------------------------ template IWriterDefaultImplementation(){ void doWrite(){ doOpen(); writefln("IWriterDefaultImplementation"); doClose(); } } //------------------------------------------------ template RWDeviceFile(){ void doOpen(){ writefln("OpenFile"); } void doClose(){ writefln("CloseFile"); } } //------------------------------------------------ template RWDeviceSpezial(){ void doOpen(){ writefln("OpenSpezial"); } void doClose(){ writefln("CloseSpezial"); } } //------------------------------------------------ class ARWFile : IReader, IWriter { mixin RWDeviceFile ; mixin IReaderDefaultImplementation ; mixin IWriterDefaultImplementation ; } class ARWSpezial : IReader, IWriter { mixin RWDeviceSpezial ; mixin IReaderDefaultImplementation ; mixin IWriterDefaultImplementation ; } class ARWasGanzSpezielles : IReader { void doOpen(){ writefln("Open WasAnderes"); } void doClose(){ writefln("Close WasAnderes"); } mixin IReaderDefaultImplementation ; } class AWNochWasSpezielles : IWriter { mixin RWDeviceFile ; void doWrite(){ doOpen(); writefln("NochWasSpezielles in datei schreiben"); doClose(); } } /* weitere lustige kombinationen */ int main(char[][] args) { ARWFile rwf = new ARWFile() ; ARWSpezial rws = new ARWSpezial() ; IReader rwgs = new ARWasGanzSpezielles(); IWriter wnws = new AWNochWasSpezielles(); rwf.doRead(); rwf.doWrite(); rws.doRead(); rws.doWrite(); rwgs.doRead(); wnws.doWrite(); return 0; }
-
daHa schrieb:
darueber zu diskutieren ob const wie in c++ mehr sinn macht wuerd die naechsten 20 seiten sinnlos hin und her fabrizieren.
Darum geht es doch gar nicht. Die Frage war lediglich, ob D den gleichen Umfang an const Semantik bietet. Offensichtlich ist dem nicht so. Das ist vollkommen wertungsfrei zu sehen.
Und dein Beispiel mit den Mixins, das sieht für mich sehr nach Präprozessor aus. Sehe ich aber nicht nur als unnütz, sondern sogar eher negativ. So kann ganz schnell das Design leiden. Kann denn die Implementation hier sicherstellen, dass das selbe Mixin auch nur eine Instanz im Speicher anlegt? So wie es zB wäre, wenn man den Basisklassen/Interfaces gleich eine passende default doRead und doWrite Implementation spendieren würde.
-
ein vergleich mit preprocessor (makros) ist sicher angebracht, allerdings kommen mir D mixin doch weit maechtiger vor.
unnütz find ich es nicht, ob das jetzt negativ ist ist bewertungssache.
viele java oder c# programmierer finden auch in C++ sachen negativ und unnuetz.
obriges bsp ist eigentlich ein bsp fuer mehrfachvererbung, die es in D eigenglich nicht gibt, aber durch mixin doch realtiv unaufwendig und flexibel realisierbar ist, glaub mit java oder c# waers etwas aufwendiger zum implementieren
es gibt aber sicher auch noch einen haufen anderer sachen wo das ganze sinn macht bzw machen koennte
(debug release utiltest code switch usw ....)
das man damit auch haufenweise bloedsinn machen kann ist mir vorerst egal, mit c++ muss ich auch aufpassen das ich mir nicht in den eigenen fuss schiess.