Alle Elemente im Container gleich?
-
Nein, weil die simpelste Möglichkeit bereits Lambda-Ausdrücke (mit Capture) erfordert. Schlussendlich hat man recht viel Boilerplate-Syntax
Akzeptiert, lambda ist tatsaechlich Boilerplate.
-
Sone schrieb:
Kommentiert muss der Code in beiden Fällen werden.
Es geht hier nicht um die Codelänge. Selbst mit Kommentar schaut man eine Weile drauf, bevor man kapiert, was da abgeht. Die erste Version ist bereits viel klarer. Noch klarer wäre allerdings eine Schleife.
-
Noch klarer wäre allerdings eine Schleife
Jein.
Vergleich: In der Funktionalen Programmierung will man weg von expliziter Rekursion. Warum ... weil man schauen muss, wo der rekursive Aufruf passiert, auf den ersten Blick unklar ist, wie und was bei der Rekursion so alles passiert. Man hat aber Rekursionspattern durch fold-left und fold-right. Keine explizite Rekursion mehr, Rekursionschema ist klar, was passiert, wird durch die Akkumulatorfunktion beschrieben. Rekursionsschema und "Usercode"/Akkumulatorfunktion sind klar getrennt.
Gleiches gilt fuer Schleifen. Der Schleifenkopf kann ja durchaus viele verschiedene Formen annehmen. Warum sich ueber sowas Gedanken machen, durch die Algorithmen ist ein Iterationsschema vorgegeben. Im Falle von std::accumulate/all_of/... brauche ich nur das Praedikat/Accumulatorfunktion anzuschauen um zu wissen, was abgeht.
Naja, Schleifen sind im Vergleich zu Rekursion vielleicht einfacher. Trotzdem versuche ich immer Iterationsschema der expliziten Iteration vorzuziehen. Sehr dankbar bin ich deswegen fuer:
for(auto x: container)Iteratoren selbst sind mir meist zu viel Tiparbeit. Auch fuer lambda bin ich in diesem Zusammenhange dankbar, da es mir das Schreiben von Funktoren erspart.
-
otze schrieb:
Sone schrieb:
Kommentiert muss der Code in beiden Fällen werden.
Es geht hier nicht um die Codelänge.
Darum ging es mir gar nicht!
Ich habe das nur angemerkt, dass sie kommentiert werden sollten.Selbst mit Kommentar schaut man eine Weile drauf, bevor man kapiert, was da abgeht.
Genau dafür sind Kommentare da: Man muss die Zeile gar nicht angucken, das Kommentar sagt, was sie tun.
-
Fuer intuitive bedienbare Programme gibt es auch Handbuecher. Liesst du die?
-
Klare Sache:
std::is_sorted(c.begin(), c.end(), [] (int a, int b) { return a != b; });Damit gibt's sogar gleich ein debug-assert sobald der Container nicht sortiert ist. Da spart man sich die manuelle Prüfung!
-
!= ist keine strikt weak ordering.
-
Also ich bin ja fuer:
begin == end || (std::sort(begin, end), std::unique(begin, end) == begin + 1)
-
@Kellerautomat: Um auch Unterstützung für nicht-RA-Iteratoren zu bekommen, nutze
std::next.
-
Noe, std::sort braucht RA.
-
Kellerautomat schrieb:
Noe, std::sort braucht RA.

-
knivil schrieb:
!= ist keine strikt weak ordering.
Daher das hilfreiche debug assert.

-
Für Mathematiker:
set{c.begin(), c.end()}.size() <= 1
-
Bashar schrieb:
Für Mathematiker:
set{c.begin(), c.end()}.size() <= 1Das ist schön!

-
Wie waere es mit rotate_copy + equal?
-
Bashar schrieb:
Für Mathematiker:
set{c.begin(), c.end()}.size() <= 1Das ist schön, aber hat unnötig hohe Komplexität und kein Short Circuit.
Sone schrieb:
equal(begin(c), prev(end(c)), next(begin(c)))Das braucht
BidirectionalIterator, theoretisch würdeInputIteratorausreichen.Ich schlage vor:
template<class InputIt] bool all_equal(InputIt first, InputIt last) { if(first == last) return true; typedef decltype(*first) T; T elem = *first++; return find_if(first, last, [&](const T& e) { return e != elem }) == last; }Wenn man die Kopie vermeiden möchte, kann man
e == *firstals Prädikat nehmen, aber dann braucht man wiederForwardIterator.
-
ipsec schrieb:
Bashar schrieb:
Für Mathematiker:
set{c.begin(), c.end()}.size() <= 1Das ist schön, aber hat unnötig hohe Komplexität und kein Short Circuit.
Ich denke mal, spätestens seit der sort-unique-Lösung sind wir beim spaßigen Teil des Abends angelangt...
-
And the winner is...
-
knivil schrieb:
Noch klarer wäre allerdings eine Schleife
Jein.
Vergleich: In der Funktionalen Programmierung...
Oh Entschuldige. Ich war nicht im exakt Modus. Das haben wir gleich:
"Noch klarer wäre allerdings in C++ eine Schleife".
C++ bietet kein kurze und klare Syntax für die hier gnannten Sachen im funktionalen Programmierstil. Funktionale Programmierung in C++ ist deswegen low-level total hässlich. Natürlich verbietet dir niemand eine schön funktionale Implementation von equal_elements zu machen, aber unterhalb dieser Abstraktion ist die klarste Lösung eben die Schleife.
template<class Range> bool all_equal(Range const& range){ for(auto& x: range){ if(x != range.front()) return false; } return true; }
-
*auto&