Am einfachsten lassen sie sich diese drei Hilfsalgorithmen anhand einer Frage unterscheiden, die sie beantworten:
std::all_of→ Erfüllen alle Elemente eine bestimmte Bedingung?std::any_of→ Erfüllt mindestens ein Element eine bestimmte Bedingung?std::none_of→ Erfüllt kein Element eine bestimmte Bedingung?
Beispiel:
01: void std_all_of()
02: {
03: std::vector<int> numbers{ 2, 4, 6, 8 };
04:
05: bool result = std::all_of(
06: numbers.begin(),
07: numbers.end(),
08: [](int n) { return n % 2 == 0; }
09: );
10:
11: std::println("Result: {}", result); // result == true
12: }Hier lautet die Fragestellung: „Sind alle Zahlen gerade?”
Ja, das Ergebnis ist in diesem Beispiel wahr.
Beispiel:
01: void std_any_of()
02: {
03: std::vector<int> numbers{ 1, 3, 4, 7 };
04:
05: bool result = std::any_of(
06: numbers.begin(),
07: numbers.end(),
08: [](int n) { return n % 2 == 0; }
09: );
10:
11: std::println("Result: {}", result); // result == true
12: }Hier fragen wir: „Gibt es mindestens eine gerade Zahl?”
Ja, 4 ist gerade, also ist das Ergebnis wahr.
Wichtig ist: Es spielt keine Rolle, dass die anderen Zahlen ungerade sind.
Beispiel:
01: void std_none_of()
02: {
03: std::vector<int> numbers{ 1, 3, 5, 7 };
04:
05: bool result = std::none_of(
06: numbers.begin(),
07: numbers.end(),
08: [](int n) { return n % 2 == 0; }
09: );
10:
11: std::println("Result: {}", result); // result == true
12: }Wir fragen: Gibt es keine geraden Zahlen?
Ja, keine der Zahlen ist gerade, daher ist das Ergebnis wahr.
Eine gute Eselsbrücke ist:
std::all_of → Bedingung für alle Elemente erfüllt.
std::any_of → Bedingung für mindestens ein Element erfüllt.
std::none_of → Bedingung für kein Element erfüllt.
Unterstützen diese drei Algorithmen eine Art „Short Circuit Evaluation”?
Ja – alle drei weisen dieses optimierende Verhalten auf, sprich sie beenden die Ausführung, wenn das Endergebnis bereits vorzeitig bekannt ist.
Man kann sie sich also fast wie die logischen Operatoren && und || vorstellen:
| Algorithmus | Short Circuit Evaluation |
|---|---|
std::all_of |
≘ condition1 && condition2 && condition3 ... |
std::any_of |
≘ condition1 || condition2 || condition3 ... |
std::none_of |
≘ !condition1 && !condition2 && !condition3 ... |
Tabelle 1: Short Circuit Evaluation von std::all_of, std::any_of und std::none_of.
Hält bei dem ersten Element an, das die Bedingung nicht erfüllt.
Beispiel:
01: void std_all_of_short_circuit()
02: {
03: std::vector<int> numbers{ 2, 4, 5, 8, 10 };
04:
05: bool result = std::all_of(
06: numbers.begin(),
07: numbers.end(),
08: [](int n) {
09: return n % 2 == 0;
10: }
11: );
12: }Es gibt keinen Grund, 8 oder 10 zu untersuchen, da wir bereits mit Wert 5 wissen, dass nicht alle Elemente die Bedingung erfüllen.
Hält bei dem ersten Element an, das die Bedingung erfüllt.
Beispiel:
01: void std_any_of_short_circuit()
02: {
03: std::vector<int> numbers{ 1, 3, 4, 7, 9 };
04:
05: bool result = std::any_of(
06: numbers.begin(),
07: numbers.end(),
08: [](int n) {
09: return n % 2 == 0;
10: }
11: );
12: }Auch hier wissen wir bereits, dass mindestens ein Element (hier: Element 4) die Bedingung erfüllt.
Hält bei dem ersten Element an, das die Bedingung erfüllt.
Beispiel:
01: void std_none_of_short_circuit()
02: {
03: std::vector<int> numbers{ 1, 3, 4, 7, 9 };
04:
05: bool result = std::none_of(
06: numbers.begin(),
07: numbers.end(),
08: [](int n) {
09: return n % 2 == 0;
10: }
11: );
12: }Da std::none_of prüft, ob kein Element die Bedingung erfüllt, genügt es, ein einziges solches Element zu finden, um false zurückzugeben.
Dies ist in diesem Beispiel beim Wert 4 der Fall.
std::all_of– Wir validieren Benutzerkonten, bevor wir einen Batch-Vorgang zulassen. Die Frage lautet: Sind alle Nutzer volljährige Personen mit verifizierten E-Mail-Adressen? Dies ist eine sehr natürliche Verwendung vonstd::all_of: „Erfüllt der gesamte STL Container eine bestimmte Anforderung”?std::any_of– Erkennen, ob etwas Aufmerksamkeit erfordert. In Bezug auf das Beispiel von unten: „Gibt es mindestens einen Auftrag, der Aufmerksamkeit erfordert”?std::none_of– Sicherstellen, dass eine Sammlung keine ungültigen Elemente enthält. In Bezug auf das Beispiel von unten: „Gibt es keine .exe-Dateien”?
Beispiel:
01: void std_all_of_example()
02: {
03: struct User {
04: std::string name;
05: int age;
06: bool emailVerified;
07: };
08:
09: std::vector<User> users {
10: { "Alice", 32, true },
11: { "Bob", 25, true },
12: { "Charlie", 17, true },
13: { "Diana", 41, true }
14: };
15:
16: bool allValid = std::all_of(
17: users.begin(),
18: users.end(),
19: [](const User& user) {
20: return user.age >= 18 && user.emailVerified;
21: }
22: );
23:
24: std::println("Are all users adults with verified email addresses? {}", allValid);
25: }Ausgabe:
Are all users adults with verified email addresses? false
Beispiel:
01: void std_any_of_example()
02: {
03: struct Job {
04: int id;
05: int priority;
06: bool failed;
07: };
08:
09: std::vector<Job> jobs{
10: { 101, 1, false },
11: { 102, 2, false },
12: { 103, 5, true },
13: { 104, 3, false }
14: };
15:
16: bool needsAttention = std::any_of(
17: jobs.begin(),
18: jobs.end(),
19: [](const Job& job) {
20: return job.failed || job.priority >= 5;
21: }
22: );
23:
24: std::println("Is there at least one job that needs attention? {}", needsAttention);
25: }Ausgabe:
Is there at least one job that needs attention? true
Beispiel:
01: void std_none_of_example()
02: {
03: std::vector<std::string> filenames{
04: "report.pdf",
05: "photo.jpg",
06: "data.csv",
07: "virus.exe"
08: };
09:
10: bool safe = std::none_of(
11: filenames.begin(),
12: filenames.end(),
13: [](const std::string& filename) {
14: return filename.ends_with(".exe");
15: }
16: );
17:
18: std::println("Are there no .exe files? {}", safe);
19: }Ausgabe:
Are there no .exe files? false