Ich habe derzeit diesen Code eingerichtet und ausgeführt:
%Vor%Ich möchte es kompakter und lesbarer machen:
(*) Ich gehe davon aus, dass die Kombination bestehender Algorithmen meinen Code lesbarer macht ...
Zusätzlich zur Definition eines benutzerdefinierten Algorithmus transform_until
, wie von jrok vorgeschlagen, könnte es möglich sein, einen benutzerdefinierten Iteratoradapter zu definieren, der mit dem zugrunde liegenden Iterator iteriert, aber den Operator * () neu definiert, indem er die zugrunde liegende Referenz vor der Rückgabe ändert .
So ähnlich:
Natürlich ist das immer noch sehr roh, aber es sollte die Idee geben. Mit dem obigen Adapter könnte ich dann folgendes schreiben:
%Vor%mit den folgenden im Voraus definiert (was könnte durch einige Vorlage Magie vereinfacht werden):
%Vor%Wenn der Standard einen solchen Adapter enthalten würde, würde ich ihn verwenden, weil das bedeuten würde, dass er fehlerfrei ist, aber da dies nicht der Fall ist, werde ich meine Schleife wahrscheinlich so behalten wie sie ist.
Ein solcher Adapter würde es erlauben, existierende Algorithmen wiederzuverwenden und auf verschiedene Arten zu mischen, was heute nicht möglich ist, aber es könnte auch Nachteile haben, die ich im Moment wahrscheinlich übersehen werde ...
Ich glaube nicht, dass es einen sauberen Weg gibt, dies mit einem einzigen Standardalgorithmus zu tun. Keiner, von dem ich weiß, nimmt ein Prädikat (Sie brauchen eines, um zu entscheiden, wann früh gebrochen werden soll) und erlaubt, die Elemente der Quellsequenz zu ändern.
Sie können Ihren eigenen generischen Algorithmus schreiben, wenn Sie es wirklich "normal" machen wollen. Nennen wir es, hmm, transform_until
:
Es ist strittig, ob das besser ist als das, was du hast :) Manchmal ist eine einfache Schleife die beste Lösung.
Nachdem ich Ihre Frage besser verstanden habe, habe ich eine Idee, die funktioniert, aber Boost
Sie könnten einen transform_iterator verwenden, der toupper
aufruft alle Zeichen und benutze das als Inputiterator für find_if
oder remove_if
. Ich kenne Boost nicht genug, um ein Beispiel zu geben.
Wie @jrok darauf hinweist, transformiert der transform_iterator den Wert nur während der Iteration und ändert den ursprünglichen Container nicht. Um dies zu umgehen, sollten Sie, statt in der gleichen Reihenfolge zu arbeiten, eine neue Kopie erstellen, beispielsweise mit remove_copy_if . Dies kopiert, solange das Prädikat NICHT wahr ist, also wird std::not1
benötigt. Dies würde den remove_if
-Fall ersetzen.
Verwenden Sie std::copy
, um zu kopieren, bis der Iterator von std::find_if
zurückgegeben wird, damit der andere Fall funktioniert.
Schließlich, wenn Ihre Ausgabezeichenfolge leer ist, wird ein std::inserter
-Typ des Iterators für die Ausgabe benötigt.