Namensräume
Varianten
Aktionen

std::transform

Von cppreference.com
< cpp‎ | algorithm
 
 
Algorithmenbibliothek
Beschränkte Algorithmen und Algorithmen für Bereiche (C++20)
Beschränkte Algorithmen, z.B. ranges::copy, ranges::sort, ...
Ausführungsrichtlinien (C++17)
Nicht-modifizierende Sequenzoperationen
Stapeloperationen
(C++17)
Suchoperationen
(C++11)                (C++11)(C++11)

Modifizierende Sequenzoperationen
Kopieroperationen
(C++11)
(C++11)
Tauschoperationen
Transformationsoperationen
transform
Generierungsoperationen
Entfernungsoperationen
Ordnungsändernde Operationen
(bis C++17)(C++11)
(C++20)(C++20)
Stichprobenoperationen
(C++17)

Sortier- und verwandte Operationen
Partitionierungsoperationen
Sortieroperationen
Binäre Suchoperationen
(auf partitionierten Bereichen)
Mengenoperationen (auf sortierten Bereichen)
Zusammenführungsoperationen (auf sortierten Bereichen)
Heapoperationen
Minimum/Maximum-Operationen
(C++11)
(C++17)
Lexikographische Vergleichsoperationen
Permutationsoperationen
C-Bibliothek
Numerische Operationen
Operationen auf uninitialisiertem Speicher
 
Definiert in Header <algorithm>
template< class InputIt, class OutputIt, class UnaryOp >

OutputIt transform( InputIt first1, InputIt last1,

                    OutputIt d_first, UnaryOp unary_op );
(1) (constexpr seit C++20)
template< class ExecutionPolicy,

          class ForwardIt1, class ForwardIt2, class UnaryOp >
ForwardIt2 transform( ExecutionPolicy&& policy,
                      ForwardIt1 first1, ForwardIt1 last1,

                      ForwardIt2 d_first, UnaryOp unary_op );
(2) (seit C++17)
template< class InputIt1, class InputIt2,

          class OutputIt, class BinaryOp >
OutputIt transform( InputIt1 first1, InputIt1 last1, InputIt2 first2,

                    OutputIt d_first, BinaryOp binary_op );
(3) (constexpr seit C++20)
template< class ExecutionPolicy,

          class ForwardIt1, class ForwardIt2,
          class ForwardIt3, class BinaryOp >
ForwardIt3 transform( ExecutionPolicy&& policy,
                      ForwardIt1 first1, ForwardIt1 last1,
                      ForwardIt2 first2,

                      ForwardIt3 d_first, BinaryOp binary_op );
(4) (seit C++17)

std::transform wendet die gegebene Funktion auf die Elemente der gegebenen Eingabebereiche an und speichert das Ergebnis in einem Ausgabebereich, der bei d_first beginnt.

1) Die unäre Operation unary_op wird auf die Elemente von [first1last1) angewendet.
Wenn unary_op einen Iterator ungültig macht oder ein Element in einem der folgenden Bereiche modifiziert, ist das Verhalten undefiniert.
  • [first1last1].
  • Der Bereich von std::distance(first1, last1) + 1 Elementen beginnend bei d_first.
3) Die binäre Operation binary_op wird auf Elementpaare aus zwei Bereichen angewendet: [first1last1) und ein weiterer Bereich von std::distance(first1, last1) Elementen beginnend bei first2.
Wenn binary_op einen Iterator ungültig macht oder ein Element in einem der folgenden Bereiche modifiziert, ist das Verhalten undefiniert.
  • [first1last1].
  • Der Bereich von std::distance(first1, last1) + 1 Elementen beginnend bei first2.
  • Der Bereich von std::distance(first1, last1) + 1 Elementen beginnend bei d_first.
2,4) Dasselbe wie (1,3), aber ausgeführt gemäß policy.
Diese Überladungen nehmen an der Auflösungsauflösung teil, nur wenn alle folgenden Bedingungen erfüllt sind

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)

Inhalt

[bearbeiten] Parameter

first1, last1 - das Iteratorpaar, das den Quell-Bereich der zu transformierenden Elemente definiert
first2 - der Anfang des zweiten Bereichs der zu transformierenden Elemente, (3,4) nur
d_first - der Anfang des Zielbereichs, kann gleich first1 oder first2 sein
policy - die Ausführungsrichtlinie, die verwendet werden soll
unary_op - ein unäres Operations-Funktionsobjekt, das angewendet wird.

Die Signatur der Funktion sollte äquivalent zu folgender sein:

 Ret fun(const Type &a);

Die Signatur muss nicht const & haben.
Der Typ  Type muss so beschaffen sein, dass ein Objekt des Typs InputIt dereferenziert und dann implizit in  Type konvertiert werden kann. Der Typ Ret muss so beschaffen sein, dass ein Objekt des Typs OutputIt dereferenziert und mit einem Wert des Typs Ret zugewiesen werden kann.

binary_op - ein binäres Operations-Funktionsobjekt, das angewendet wird.

Die Signatur der Funktion sollte äquivalent zu folgender sein:

 Ret fun(const Type1 &a, const Type2 &b);

Die Signatur muss nicht const & haben.
Die Typen  Type1 und  Type2 müssen so beschaffen sein, dass Objekte der Typen InputIt1 und InputIt2 dereferenziert und dann implizit in  Type1 bzw.  Type2 konvertiert werden können. Der Typ Ret muss so beschaffen sein, dass ein Objekt des Typs OutputIt dereferenziert und mit einem Wert des Typs Ret zugewiesen werden kann.

Typanforderungen
-
InputIt, InputIt1, InputIt2 müssen die Anforderungen von LegacyInputIterator erfüllen.
-
OutputIt muss die Anforderungen an LegacyOutputIterator erfüllen.
-
ForwardIt1, ForwardIt2, ForwardIt3 müssen die Anforderungen von LegacyForwardIterator erfüllen.

[bearbeiten] Rückgabewert

Ausgabeiterator auf das Element, das dem letzten transformierten Element folgt.

[bearbeiten] Komplexität

Gegeben N als std::distance(first1, last1)

1,2) Genau N Anwendungen von unary_op.
3,4) Genau N Anwendungen von binary_op.

[bearbeiten] 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 ExecutionPolicy eine der Standardrichtlinien ist, wird std::terminate aufgerufen. Für jede andere ExecutionPolicy ist das Verhalten implementierungsabhängig.
  • Wenn dem Algorithmus der Speicher zur Neuzuweisung fehlt, wird std::bad_alloc ausgelöst.

[bearbeiten] Mögliche Implementierung

transform (1)
template<class InputIt, class OutputIt, class UnaryOp>
constexpr //< since C++20
OutputIt transform(InputIt first1, InputIt last1,
                   OutputIt d_first, UnaryOp unary_op)
{
    for (; first1 != last1; ++d_first, ++first1)
        *d_first = unary_op(*first1);
 
    return d_first;
}
transform (3)
template<class InputIt1, class InputIt2, 
         class OutputIt, class BinaryOp>
constexpr //< since C++20
OutputIt transform(InputIt1 first1, InputIt1 last1, InputIt2 first2,
                   OutputIt d_first, BinaryOp binary_op)
{
    for (; first1 != last1; ++d_first, ++first1, ++first2)
        *d_first = binary_op(*first1, *first2);
 
    return d_first;
}

[bearbeiten] Hinweise

std::transform garantiert keine geordnete Anwendung von unary_op oder binary_op. Um eine Funktion in geordneter Weise auf eine Sequenz anzuwenden oder eine Funktion anzuwenden, die die Elemente einer Sequenz modifiziert, verwenden Sie std::for_each.

[bearbeiten] Beispiel

#include <algorithm>
#include <cctype>
#include <iomanip>
#include <iostream>
#include <string>
#include <utility>
#include <vector>
 
void print_ordinals(const std::vector<unsigned>& ordinals)
{
    std::cout << "ordinals: ";
    for (unsigned ord : ordinals)
        std::cout << std::setw(3) << ord << ' ';
    std::cout << '\n';
}
 
char to_uppercase(unsigned char c)
{
    return std::toupper(c);
}
 
void to_uppercase_inplace(char& c)
{
    c = to_uppercase(c);
}
 
void unary_transform_example(std::string& hello, std::string world)
{
    // Transform string to uppercase in-place
 
    std::transform(hello.cbegin(), hello.cend(), hello.begin(), to_uppercase);
    std::cout << "hello = " << std::quoted(hello) << '\n';
 
    // for_each version (see Notes above)
    std::for_each(world.begin(), world.end(), to_uppercase_inplace);
    std::cout << "world = " << std::quoted(world) << '\n';
}
 
void binary_transform_example(std::vector<unsigned> ordinals)
{
    // Transform numbers to doubled values
 
    print_ordinals(ordinals);
 
    std::transform(ordinals.cbegin(), ordinals.cend(), ordinals.cbegin(),
                   ordinals.begin(), std::plus<>{});
 
    print_ordinals(ordinals);
}
 
int main()
{
    std::string hello("hello");
    unary_transform_example(hello, "world");
 
    std::vector<unsigned> ordinals;
    std::copy(hello.cbegin(), hello.cend(), std::back_inserter(ordinals));
    binary_transform_example(std::move(ordinals));
}

Ausgabe

hello = "HELLO"
world = "WORLD"
ordinals:  72  69  76  76  79 
ordinals: 144 138 152 152 158

[bearbeiten] Fehlerberichte

Die folgenden Verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.

DR angewendet auf Verhalten wie veröffentlicht Korrigiertes Verhalten
LWG 242 C++98 unary_op und binary_op konnten keine Seiteneffekte haben sie dürfen die beteiligten Bereiche nicht modifizieren

[bearbeiten] Siehe auch

wendet ein unäres Funktionsobjekt auf Elemente aus einem Bereich an
(Funktion-Template) [bearbeiten]
Wendet eine Funktion auf einen Elementbereich an
(Algorithmus-Funktionsobjekt)[edit]