Namensräume
Varianten
Aktionen

std::ranges::copy, std::ranges::copy_if, std::ranges::copy_result, std::ranges::copy_if_result

Von cppreference.com
< cpp‎ | algorithm‎ | ranges
 
 
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
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
 
Eingeschränkte Algorithmen
Alle Namen in diesem Menü gehören zum Namespace std::ranges
Nicht-modifizierende Sequenzoperationen
Modifizierende Sequenzoperationen
Partitionierungsoperationen
Sortieroperationen
Binäre Suchoperationen (auf sortierten Bereichen)
       
       
Mengenoperationen (auf sortierten Bereichen)
Heapoperationen
Minimum/Maximum-Operationen
       
       
Permutationsoperationen
Faltoperationen
Operationen auf uninitialisiertem Speicher
Rückgabetypen
 
Definiert in Header <algorithm>
Aufruf-Signatur
template< std::input_iterator I, std::sentinel_for<I> S, std::weakly_incrementable O >

requires std::indirectly_copyable<I, O>
constexpr copy_result<I, O>

    copy( I first, S last, O result );
(1) (seit C++20)
template< ranges::input_range R, std::weakly_incrementable O >

requires std::indirectly_copyable<ranges::iterator_t<R>, O>
constexpr copy_result<ranges::borrowed_iterator_t<R>, O>

    copy( R&& r, O result );
(2) (seit C++20)
template< std::input_iterator I, std::sentinel_for<I> S, std::weakly_incrementable O,

          class Proj = std::identity,
          std::indirect_unary_predicate<std::projected<I, Proj>> Pred >
requires std::indirectly_copyable<I, O>
constexpr copy_if_result<I, O>

    copy_if( I first, S last, O result, Pred pred, Proj proj = {} );
(3) (seit C++20)
template< ranges::input_range R, std::weakly_incrementable O,

          class Proj = std::identity,
          std::indirect_unary_predicate<
              std::projected<ranges::iterator_t<R>, Proj>> Pred >
requires std::indirectly_copyable<ranges::iterator_t<R>, O>
constexpr copy_if_result<ranges::borrowed_iterator_t<R>, O>

    copy_if( R&& r, O result, Pred pred, Proj proj = {} );
(4) (seit C++20)
Hilfstypen
template< class I, class O >
using copy_result = ranges::in_out_result<I, O>;
(5) (seit C++20)
template< class I, class O >
using copy_if_result = ranges::in_out_result<I, O>;
(6) (seit C++20)

Kopiert die Elemente im Bereich, definiert durch [firstlast), in einen anderen Bereich, der bei result beginnt.

1) Kopiert alle Elemente im Bereich [firstlast), beginnend bei first und fortschreitend bis last - 1. Das Verhalten ist undefiniert, wenn result innerhalb des Bereichs [firstlast) liegt. In diesem Fall kann stattdessen ranges::copy_backward verwendet werden.
3) Kopiert nur die Elemente, für die das Prädikat pred zurückgibt true. Die relative Reihenfolge der kopierten Elemente bleibt erhalten. Das Verhalten ist undefiniert, wenn sich die Quell- und Zielbereiche überschneiden.
2,4) Entspricht (1,3), verwendet aber r als Quellbereich, so als ob ranges::begin(r) als first und ranges::end(r) als last verwendet würden.

Die auf dieser Seite beschriebenen funktionsähnlichen Entitäten sind Algorithmus-Funktionsobjekte (informell als niebloids bekannt), d.h.

Inhalt

[Abschnitt bearbeiten] Parameter

first, last - das Iterator-Sentinel-Paar, das den Bereich der zu kopierenden Elemente definiert
r - der Bereich der zu kopierenden Elemente
Ergebnis - der Anfang des Zielbereichs.
pred - Prädikat, das auf die projizierten Elemente angewendet wird
proj - Projektion, die auf die Elemente angewendet wird

[Abschnitt bearbeiten] Rückgabewert

Ein ranges::in_out_result, das einen Eingabeiterator enthält, der gleich last ist, und einen Ausgabeiterator hinter dem letzten kopierten Element.

[Abschnitt bearbeiten] Komplexität

1,2) Genau last - first Zuweisungen.
3,4) Genau last - first Anwendungen des Prädikats und der Projektion, zwischen 0 und last - first Zuweisungen (Zuweisung für jedes Element, für das das Prädikat true zurückgibt, abhängig vom Prädikat und den Eingabedaten).

[Abschnitt bearbeiten] Hinweise

In der Praxis vermeiden Implementierungen von ranges::copy Mehrfachzuweisungen und verwenden Massenkopierfunktionen wie std::memmove, wenn der Werttyp TriviallyCopyable ist und die Iteratortypen contiguous_iterator erfüllen.

Beim Kopieren von überlappenden Bereichen ist ranges::copy geeignet, wenn nach links kopiert wird (Anfang des Zielbereichs liegt außerhalb des Quellbereichs), während ranges::copy_backward geeignet ist, wenn nach rechts kopiert wird (Ende des Zielbereichs liegt außerhalb des Quellbereichs).

[Abschnitt bearbeiten] Mögliche Implementierung

copy (1)(2)
struct copy_fn
{
    template<std::input_iterator I, std::sentinel_for<I> S, std::weakly_incrementable O>
    requires std::indirectly_copyable<I, O>
    constexpr ranges::copy_result<I, O> operator()(I first, S last, O result) const
    {
        for (; first != last; ++first, (void)++result)
            *result = *first;
        return {std::move(first), std::move(result)};
    }
 
    template<ranges::input_range R, std::weakly_incrementable O>
    requires std::indirectly_copyable<ranges::iterator_t<R>, O>
    constexpr ranges::copy_result<ranges::borrowed_iterator_t<R>, O>
        operator()(R&& r, O result) const
    {
        return (*this)(ranges::begin(r), ranges::end(r), std::move(result));
    }
};
 
inline constexpr copy_fn copy;
copy_if (3)(4)
struct copy_if_fn
{
    template<std::input_iterator I, std::sentinel_for<I> S, std::weakly_incrementable O,
             class Proj = std::identity,
             std::indirect_unary_predicate<std::projected<I, Proj>> Pred>
    requires std::indirectly_copyable<I, O>
    constexpr ranges::copy_if_result<I, O>
        operator()(I first, S last, O result, Pred pred, Proj proj = {}) const
    {
        for (; first != last; ++first)
            if (std::invoke(pred, std::invoke(proj, *first)))
            {
                *result = *first;
                ++result;
            }
        return {std::move(first), std::move(result)};
    }
 
    template<ranges::input_range R, std::weakly_incrementable O,
             class Proj = std::identity,
             std::indirect_unary_predicate<
                 std::projected<ranges::iterator_t<R>, Proj>> Pred>
    requires std::indirectly_copyable<ranges::iterator_t<R>, O>
    constexpr ranges::copy_if_result<ranges::borrowed_iterator_t<R>, O>
        operator()(R&& r, O result, Pred pred, Proj proj = {}) const
    {
        return (*this)(ranges::begin(r), ranges::end(r), std::move(result),
                       std::ref(pred), std::ref(proj));
    }
};
 
inline constexpr copy_if_fn copy_if;

[Abschnitt bearbeiten] Beispiel

Der folgende Code verwendet ranges::copy, um sowohl den Inhalt eines std::vector in einen anderen zu kopieren als auch den resultierenden std::vector anzuzeigen.

#include <algorithm>
#include <iostream>
#include <iterator>
#include <numeric>
#include <vector>
 
int main()
{
    std::vector<int> source(10);
    std::iota(source.begin(), source.end(), 0);
    std::vector<int> destination;
    std::ranges::copy(source.begin(), source.end(), std::back_inserter(destination));
 
// or, alternatively,
//  std::vector<int> destination(source.size());
//  std::ranges::copy(source.begin(), source.end(), destination.begin());
// either way is equivalent to
//  std::vector<int> destination = source;
 
    std::cout << "Destination contains: ";
    std::ranges::copy(destination, std::ostream_iterator<int>(std::cout, " "));
    std::cout << '\n';
 
    std::cout << "Odd numbers in destination are: ";
    std::ranges::copy_if(destination, std::ostream_iterator<int>(std::cout, " "),
                         [](int x) { return (x % 2) == 1; });
    std::cout << '\n';
}

Ausgabe

Destination contains: 0 1 2 3 4 5 6 7 8 9
Odd numbers in destination are: 1 3 5 7 9

[Abschnitt bearbeiten] Siehe auch

Kopiert einen Elementbereich in umgekehrter Reihenfolge
(Algorithmus-Funktionsobjekt)[edit]
Erstellt eine Kopie eines Bereichs, der umgekehrt ist
(Algorithmus-Funktionsobjekt)[edit]
Kopiert eine Anzahl von Elementen an einen neuen Speicherort
(Algorithmus-Funktionsobjekt)[edit]
Weist einem Elementbereich einen bestimmten Wert zu
(Algorithmus-Funktionsobjekt)[edit]
Kopiert einen Bereich von Elementen und lässt diejenigen aus, die bestimmte Kriterien erfüllen
(Algorithmus-Funktionsobjekt)[edit]
Kopiert einen Elementbereich an einen neuen Speicherort
(Funktionstempelat) [edit]