D Programmierung
-
gc schrieb:
Neuigkeiten in der Aktuellen Version:
...
speicherleck behoben
...
Ja, auch unter Java können bestimmte Arten von Speicherlecks auftreten.
Der GC räumt zwar alles weg, auf das es keine Referenz mehr gibt, aber es kann ja auch mal passieren, dass man irgendwo aus Versehen Referenzen "anhäuft", also behält, obwohl man sie nicht mehr braucht. Solche Lecks kann man mit dem passenden Profiler allerdings ganz gut finden.
-
Aber Gott sei Dank muss man sich in GC-Sprachen um die Speicherverwaltung ja keine Sorgen machen...</sarkasmus>
-
GodBeBlessed schrieb:
Aber Gott sei Dank muss man sich in GC-Sprachen um die Speicherverwaltung ja keine Sorgen machen...</sarkasmus>
Wer sich beim programmieren keine Gedanken macht, sollte es lieber sein lassen... ganz egal welche Sprache er benutzt

-
JBeni schrieb:
GodBeBlessed schrieb:
Aber Gott sei Dank muss man sich in GC-Sprachen um die Speicherverwaltung ja keine Sorgen machen...</sarkasmus>
Wer sich beim programmieren keine Gedanken macht, sollte es lieber sein lassen... ganz egal welche Sprache er benutzt

Soll das heißen, dass die macher von Jamp mit dem Programmieren aufhören sollen?

-
Hier entsteht ein harmonia wiki:
http://dannerbeck.net/index.php?option=com_mambowiki&Itemid=16Ausserdem wird sprungmarke immer voller.
http://sprungmarke.netFreut mich dass D doch soviel Diskussion auslösen kann

-
Optimizer schrieb:
daHa schrieb:
lesbarkeit ist von for schleifen mindestens genauso gut, wenn nicht besser
typedef std::map<MyKey, MyValue*>::const_iterator Iterator; for( Iterator i = myMap.begin(); i != myMap.end(); ++i ) { cout << (*i)->getMember(); }foreach( MyValue v in myMap ) { Console.Out.WriteLine(v.getMember()); }q.e.d.
{...}#include <map> #include <iostream> #include <algorithm> #include <boost/lambda/lambda.hpp> #include <boost/lambda/bind.hpp> using namespace boost::lambda; using namespace std; for_each( myMap.begin(), myMap.end(), cout << bind( &MyValue::getMember, _1 ) );
-
Bei ner map gehts leider nicht ganz so einfach, aber ist nicht viel schwerer:
typedef std::map<MyKey, MyValue*> M; for_each( myMap.begin(), myMap.end(), cout << bind( &MyValue::getMember, bind( &M::value_type::second, _1 ) ) );
-
Boost::Lambda schrieb:
for_each( myMap.begin(), myMap.end(), cout << bind( &MyValue::getMember, _1 ) );Ich finde, dass es immer noch nicht vergleichbar mit dem foreach-Beispiel von mir ist. Klar, es passt in eine Zeile, aber es sieht halt trotzdem nicht geil aus. Vor allem wenn der Rumpf dann doch mal aus mehr besteht als einer Ausgabe.
Gibt's wenigstens einen Overload, wo man nicht begin() und end() sagen muss? Ich bin jedenfalls nach wie vor nicht davon überzeugt, dass man ein schönes foreach selber basteln kann.Bei einer Map würde es in C# übrigens so aussehen (man kriegt Pairs, mein Beispiel war nicht ganz korrekt):
Dictionary<int, string> dictionary; ... foreach( KeyValuePair<int, string> pair in dictionary ) { Console.Out.WriteLine(pair.Value.GetMember()); }
-
Optimizer schrieb:
Gibt's wenigstens einen Overload, wo man nicht begin() und end() sagen muss?
Das ist afaik nicht im Standard aber hin und wieder trifft man mal auf
template <typename Cont, typename Func> void for_all(Cont & cont, Func func) { std::for_each(cont.begin(), cont.end(), func); }Das ist meiner Meinung nach in sofern unschön da C++ keine Interfaces hat.
Java verlangt glaube ich das der Container von Enumerable oder so ableitet.
In C++ ist man aber so gesehen an keine Namenskonvention gebunden und man kann die Methoden genauso gut auch getBegin() und getEnd() nennen, was zur Folge hat das for_all nicht funktioniert.Optimizer schrieb:
Ich bin jedenfalls nach wie vor nicht davon überzeugt, dass man ein schönes foreach selber basteln kann.
Eric Niebler hat ein FOR_EACH Makro entwickelt.
Falls du's noch nicht kennst: http://www.artima.com/cppsource/foreach.htmlVielleicht gefällt's dir ja. Ich komme ohne aus..
-
Optimizer schrieb:
Boost::Lambda schrieb:
for_each( myMap.begin(), myMap.end(), cout << bind( &MyValue::getMember, _1 ) );Ich finde, dass es immer noch nicht vergleichbar mit dem foreach-Beispiel von mir ist. Klar, es passt in eine Zeile, aber es sieht halt trotzdem nicht geil aus. Vor allem wenn der Rumpf dann doch mal aus mehr besteht als einer Ausgabe.
Deswegen werd ich mich auch davor hüten den Auszug aus deinem Spiel mit for_each nachzubauen, bei langen Variablennamen wird es einfach zu unübersichtlich, ohne die Variablen zuvor als lambda-variablen anzulegen (und dann ist es ja kein echtes foreach mehr).
-
typedef std::map<MyKey, MyValue*> M; for_each( myMap.begin(), myMap.end(), cout << bind( &MyValue::getMember, bind( &M::value_type::second, _1 ) ) );Du hast recht. Das ist ja gleich viel übersichtlicher, als jede gewöhnliche for each Schleife in anderen Sprachen. Einfach genial, vorallem, wenn man mal etwas mehr mit den Werten machen will.

-
Eric Nieblers foreach Makro sieht ja viel versprechend aus. Wenn jetzt noch jemand das Problem mit
BOOST_FOR_EACH(pair<int, char>&p, my_map){ }lösst bin ich zufrieden.
Denn Artikel sollte sich jeder mal durch lesen. Schon erstaunlich wie man eine const& und einen ?: Zweck entfremden kann.

-
gibts ausser diesem killerargument
Klar, es passt in eine Zeile, aber es sieht halt trotzdem nicht geil aus.
noch andere argumente warum ein foreach wie in anderen sprachen implementiert so notwendig, toll oder sonstiges ist?
wie zb das der compiler einen besseren code generiert?tipparbeit sparen die nicht mal 0,0000000001% der projektzeit ausmacht wuerd ich auch nicht so als killerargument ansehn.
-
Für dich ist gar nichts ein Argument. Ich kann auch gleich zu einer Wand reden. Ich fang jetzt gar nicht an zu erklären, warum es gar nicht um die reine Tipparbeit geht.
-
Ben04 schrieb:
Eric Nieblers foreach Makro sieht ja viel versprechend aus. Wenn jetzt noch jemand das Problem mit
BOOST_FOR_EACH(pair<int, char>&p, my_map){ }lösst bin ich zufrieden.
Denn Artikel sollte sich jeder mal durch lesen. Schon erstaunlich wie man eine const& und einen ?: Zweck entfremden kann.

Das sieht ja schon echt nicht schlecht aus. Nen anderen Namen vielleicht noch (trivial) und man kann es fast benutzen. Den Nachteil, dass mögliche Fehlermeldungen auf Code verweisen, den der Programmierer nicht sieht, kriegt man eh nicht los. Das Ding seh ich mir heute Abend mal an.

-
setzt eigenlich eine/jede foreach sprachimplementation voraus das die container die mit foreach funktionieren ein gemeinsames interface besitzen?
-
daHa schrieb:
setzt eigenlich eine/jede foreach sprachimplementation voraus das die container die mit foreach funktionieren ein gemeinsames interface besitzen?
Ne, das ist nur bei Sprachen so die kein festes Typsystem haben und eh alles ein Object ist.
-
setzt eigenlich eine/jede foreach sprachimplementation voraus das die container die mit foreach funktionieren ein gemeinsames interface besitzen?
Ich kann jetzt nur für C# sprechen: Jein.
In C# gibt es 2 Möglichkeiten eine Collection "enumerable" zu machen.
1. Das Interface IEnumerable implementieren
2. Einfach nur die Methode GetEnumerator zur Verüfung stellen, also IEnumerable "quasi-implementieren"
-
uberfrickler schrieb:
2. Einfach nur die Methode GetEnumerator zur Verüfung stellen, also IEnumerable "quasi-implementieren"
Hmmmm also für C# stimmt das nicht. Folgender Code compiliert nicht:
using System.Collections; using System.Collections.Generic; namespace Test { static class Program { private static void Main() { Test<int> test = null; foreach( int i in test ) { } } private class Test<T> { public IEnumerator<T> GetEnumerator() { return null; } IEnumerator IEnumerable.GetEnumerator() { return null; } } } }Mit ": IEnumerable<T>" allerdings schon. In C# musst du dieses Interface wirklich ausdrücklich implementieren, so dass deine Collection diesen Typ auch hat.
Für andere Sprachen muss das allerdings keine zwingende Voraussetzung sein. Der Compiler könnte einfach ausprobieren, ob es passende begin() und end() gibt und entsprechend meckern. In C++ funktionieren die Templates und Makros auch nach diesem Prinzip. Die Schnittstelle muss halt vorhanden sein, sonst compiliert der Code nicht. In Sprachen, die ein Sprachkonstrukt für Schnittstellen haben, wird dieses dann eher vorausgesetzt.
-
Mit ": IEnumerable<T>" allerdings schon. In C# musst du dieses Interface wirklich ausdrücklich implementieren, so dass deine Collection diesen Typ auch hat.
Das liegt aber auch nur daran, weil du in deinem Beispiel versuchst ein Interface explizit zu implementieren. Versuch mal folgendes:
using System.Collections; using System.Collections.Generic; namespace Test { static class Program { private static void Main() { Test<int> test = null; foreach( int i in test ) { } } private class Test<T> { public IEnumerator<T> GetEnumerator() { return null; } } } }Ansonsten sieh dir mal die C# Language Specification an, hab jetzt leider keinen offiziellen Link, aber folgendes sollte es auch tun:
http://www.jaggersoft.com/csharp_standard/15.8.4.htm (Paragraph 4)