std::transform_inclusive_scan
| Definiert in der Header-Datei <numeric> |
||
| template< class InputIt, class OutputIt, class BinaryOp, class UnaryOp > |
(1) | (seit C++17) (constexpr seit C++20) |
| template< class ExecutionPolicy, class ForwardIt1, class ForwardIt2, |
(2) | (seit C++17) |
| template< class InputIt, class OutputIt, class BinaryOp, class UnaryOp, class T > |
(3) | (seit C++17) (constexpr seit C++20) |
| template< class ExecutionPolicy, class ForwardIt1, class ForwardIt2, |
(4) | (seit C++17) |
[0, std::distance(first, last)), werden nacheinander folgende Operationen ausgeführt:- Erstellt eine Sequenz, die aus den Werten gebildet wird, die von den Elementen von
[first,iter]der Reihe nach durch unary_op transformiert werden, wobei iter der nächste ite Iterator von first ist. - Berechnet die verallgemeinerte nichtkommutative Summe der Sequenz über binary_op.
- Weist das Ergebnis *dest zu, wobei dest der nächste ite Iterator von d_first ist.
[first, iter] der Reihe nach gebildet.|
std::is_execution_policy_v<std::decay_t<ExecutionPolicy>> ist true. |
(bis C++20) |
|
std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>> ist true. |
(seit C++20) |
Die *verallgemeinerte nicht-kommutative Summe* einer Sequenz von Elementen über eine binäre Operation binary_op ist wie folgt definiert:
- Wenn die Sequenz nur ein Element enthält, ist die Summe der Wert des Elements.
- Andernfalls werden die folgenden Operationen der Reihe nach ausgeführt
- Wählt zwei beliebige benachbarte Elemente elem1 und elem2 aus der Sequenz aus.
- Berechnet binary_op(elem1, elem2) und ersetzt die beiden Elemente in der Sequenz durch das Ergebnis.
- Wiederholt die Schritte 1 und 2, bis nur noch ein Element in der Sequenz verbleibt.
Das Ergebnis ist nicht deterministisch, wenn die binary_op nicht assoziativ ist (z. B. Gleitkommaaddition).
Bei Überladungen (1,2), wenn binary_op(unary_op(*first), unary_op(*first)) nicht in den Werttyp von decltype(first) konvertierbar ist, ist das Programm schlecht geformt.
Bei Überladungen (3,4), wenn einer der folgenden Werte nicht in T konvertierbar ist, ist das Programm schlecht geformt
- binary_op(init, init)
- binary_op(init, unary_op(*first))
- binary_op(unary_op(*first), unary_op(*first))
Wenn eine der folgenden Bedingungen erfüllt ist, ist das Verhalten undefiniert
- Bei Überladungen (1,2) ist der Werttyp von decltype(first) nicht MoveConstructible.
- Bei Überladungen (3,4) ist
Tnicht MoveConstructible. - unary_op oder binary_op modifiziert ein Element von
[first,last). - unary_op oder binary_op macht einen Iterator oder ein Teilbereich von
[first,last]ungültig.
Inhalt |
[edit] Parameter
| first, last | - | das Iteratorenpaar, das den Bereich der zu summierenden Elemente definiert |
| d_first | - | der Anfang des Zielbereichs; kann gleich first sein |
| policy | - | die Ausführungsrichtlinie, die verwendet werden soll |
| init | - | der Anfangswert |
| unary_op | - | Ein unärer FunctionObject, der auf jedes Element des Eingabebereichs angewendet wird. Der Rückgabetyp muss als Eingabe für binary_op akzeptabel sein. |
| binary_op | - | Ein binärer FunctionObject, der auf das Ergebnis von unary_op, die Ergebnisse anderer binary_op und init angewendet wird, falls angegeben |
| Typanforderungen | ||
-InputIt muss die Anforderungen von LegacyInputIterator erfüllen. | ||
-OutputIt muss die Anforderungen an LegacyOutputIterator erfüllen. | ||
-ForwardIt1, ForwardIt2 müssen die Anforderungen an LegacyForwardIterator erfüllen. | ||
[edit] Rückgabewert
Iterator auf das Element nach dem letzten geschriebenen Element.
[edit] Komplexität
Gegeben N als std::distance(first, last)
[edit] Ausnahmen
Die Überladungen mit einem Template-Parameter namens ExecutionPolicy berichten Fehler wie folgt
- Wenn die Ausführung einer Funktion, die als Teil des Algorithmus aufgerufen wird, eine Ausnahme auslöst und
ExecutionPolicyeine der Standardrichtlinien ist, wird std::terminate aufgerufen. Für jede andereExecutionPolicyist das Verhalten implementierungsabhängig. - Wenn dem Algorithmus der Speicher zur Neuzuweisung fehlt, wird std::bad_alloc ausgelöst.
[edit] Hinweise
unary_op wird niemals auf init angewendet.
Der Parameter init erscheint zuletzt, was sich von std::transform_exclusive_scan unterscheidet, da er für diese Funktion optional ist.
[edit] Beispiel
#include <functional> #include <iostream> #include <iterator> #include <numeric> #include <vector> int main() { std::vector data{3, 1, 4, 1, 5, 9, 2, 6}; auto times_10 = [](int x) { return x * 10; }; std::cout << "10 times exclusive sum: "; std::transform_exclusive_scan(data.begin(), data.end(), std::ostream_iterator<int>(std::cout, " "), 0, std::plus<int>{}, times_10); std::cout << "\n10 times inclusive sum: "; std::transform_inclusive_scan(data.begin(), data.end(), std::ostream_iterator<int>(std::cout, " "), std::plus<int>{}, times_10); std::cout << '\n'; }
Ausgabe
10 times exclusive sum: 0 30 40 80 90 140 230 250 10 times inclusive sum: 30 40 80 90 140 230 250 310
[edit] Siehe auch
| berechnet die partielle Summe einer Elementreihe (Funktionstemplate) | |
| Wendet eine Funktion auf einen Elementbereich an und speichert die Ergebnisse in einem Zielbereich (Funktionstempelat) | |
| (C++17) |
ähnlich wie std::partial_sum, schließt das i-te Eingabeelement in die i-te Summe ein (Funktionstemplate) |
| (C++17) |
wendet eine aufrufbare Funktion an und berechnet dann einen exklusiven Scan (Funktionstemplate) |