Namensräume
Varianten
Aktionen

std::experimental::ranges::copy, std::experimental::ranges::copy_if

Von cppreference.com
< cpp‎ | experimental‎ | ranges
 
 
 
 
 
template< InputIterator I, Sentinel<I> S, WeaklyIncrementable O >

    requires IndirectlyCopyable<I, O>
ranges::tagged_pair<tag::in(I), tag::out(O)>

    copy( I first, S last, O result );
(1) (Ranges TS)
template< InputRange R, WeaklyIncrementable O >

    requires IndirectlyCopyable<ranges::iterator_t<R>, O>
ranges::tagged_pair<tag::in(ranges::safe_iterator_t<R>), tag::out(O)>

    copy( R&& r, O result );
(2) (Ranges TS)
template< InputIterator I, Sentinel<I> S, WeaklyIncrementable O,

          class Proj = ranges::identity,
          IndirectUnaryPredicate<projected<I, Proj>> Pred >
    requires IndirectlyCopyable<I, O>
ranges::tagged_pair<tag::in(I), tag::out(O)>

    copy_if( I first, S last, O result, Pred pred, Proj proj = Proj{} );
(3) (Ranges TS)
template< InputRange R, WeaklyIncrementable O,

          class Proj = ranges::identity,
          IndirectUnaryPredicate<projected<ranges::iterator_t<R>, Proj>> Pred >
    requires IndirectlyCopyable<iterator_t<R>, O>
ranges::tagged_pair<tag::in(ranges::safe_iterator_t<R>), tag::out(O)>

    copy_if( R&& r, O result, Pred pred, Proj proj = Proj{} );
(4) (Ranges TS)

Kopiert Elemente im Quellbereich ([firstlast) oder r) in den Zielbereich beginnend bei result, beginnend mit dem ersten Element im Quellbereich und fortfahrend bis zum letzten.

1) Kopiert alle Elemente im Bereich [firstlast). Für jede nicht-negative Ganzzahl n < (last - first), wird *(result + n) = *(first + n) ausgeführt. Das Verhalten ist undefiniert, wenn result im Bereich [firstlast) liegt. In diesem Fall kann ranges::copy_backward stattdessen verwendet werden.
2) Wie (1), aber verwendet r als Quellbereich, als ob ranges::copy(ranges::begin(r), ranges::end(r), result); wobei result möglicherweise nicht kopiert wird.
3) Kopiert nur die Elemente, für die das Prädikat pred true zurückgibt, wenn es auf den Wert des Elements angewendet wird, wie durch die Projektion proj projiziert. Die Reihenfolge der kopierten Elemente bleibt erhalten. Das Verhalten ist undefiniert, wenn sich der Quell- und der Zielbereich überschneiden.
4) Wie (3), aber verwendet r als Quellbereich, als ob ranges::copy_if(ranges::begin(r), ranges::end(r), result, pred, proj); wobei result, pred und proj möglicherweise nicht kopiert werden.

Ungeachtet der oben gezeigten Deklarationen ist die tatsächliche Anzahl und Reihenfolge der Template-Parameter für Algorithmusdeklarationen nicht spezifiziert. Wenn also explizite Template-Argumente beim Aufruf eines Algorithmus verwendet werden, ist das Programm wahrscheinlich nicht portabel.

Inhalt

[edit] Parameter

first, last - der Bereich der zu kopierenden Elemente
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

[edit] Rückgabewert

Ein tagged_pair Objekt, das die folgenden beiden Member enthält

  • Der erste Member mit dem Tag tag::in ist der Iterator hinter dem Ende des Quellbereichs (d.h. ein Iterator vom Typ I, der gleich dem Sentinel last ist).
  • Der zweite Member mit dem Tag tag::out ist der Iterator hinter dem Ende des Ergebnisbereichs.

[edit] Komplexität

1) Genau ranges::distance(first, last) Zuweisungen.
2) Genau ranges::distance(r) Zuweisungen.
3) Genau ranges::distance(first, last) Anwendungen der entsprechenden Projektion und des Prädikats.
4) Genau ranges::distance(r) Anwendungen der entsprechenden Projektion und des Prädikats.

[edit] Mögliche Implementierungen

Erste Version
template<InputIterator I, Sentinel<I> S, WeaklyIncrementable O>
    requires IndirectlyCopyable<I, O>()
ranges::tagged_pair<tag::in(I), tag::out(O)>
    copy(I first, S last, O result)
{
    for (; first != last; ++first, (void)++result)
        *result = *first;
    return {first, result};
}
Zweite Version
template<InputRange R, WeaklyIncrementable O>
    requires IndirectlyCopyable<ranges::iterator_t<R>, O>()
ranges::tagged_pair<tag::in(ranges::safe_iterator_t<R>), tag::out(O)>
    copy(R&& r, O result)
{
   return ranges::copy(ranges::begin(r), ranges::end(r), result);
}
Dritte Version
template<InputIterator I, Sentinel<I> S, WeaklyIncrementable O,
         class Proj = ranges::identity,
         IndirectUnaryPredicate<projected<I, Proj>> Pred>
    requires IndirectlyCopyable<I, O>()
ranges::tagged_pair<tag::in(I), tag::out(O)>
    copy_if(I first, S last, O result, Pred pred, Proj proj = Proj{})
{
    for (; first != last; ++first)
        if (ranges::invoke(pred, ranges::invoke(proj, *first)))
        {
            *result = *first;
            ++result;
        }
    return {first, result};
}
Vierte Version
template<InputRange R, WeaklyIncrementable O,
         class Proj = ranges::identity,
         IndirectUnaryPredicate<projected<ranges::iterator_t<R>, Proj>> Pred>
    requires IndirectlyCopyable<ranges::iterator_t<R>, O>()
ranges::tagged_pair<tag::in(ranges::safe_iterator_t<R>), tag::out(O)>
    copy_if(R&& r, O result, Pred pred, Proj proj = Proj{})
{
    return ranges::copy_if(ranges::begin(r), ranges::end(r), result, pred, proj);
}

[edit] Beispiel

Der folgende Code verwendet copy, um sowohl den Inhalt eines Vektors in einen anderen zu kopieren als auch den resultierenden Vektor anzuzeigen

#include <experimental/ranges/algorithm>
#include <experimental/ranges/iterator>
#include <iostream>
#include <numeric>
#include <vector>
 
int main()
{
    // see https://cppreference.de/w/cpp/language/namespace_alias
    namespace ranges = std::experimental::ranges;
 
    std::vector<int> from_vector(10);
    std::iota(from_vector.begin(), from_vector.end(), 0);
 
    std::vector<int> to_vector;
    ranges::copy_if(from_vector.begin(), from_vector.end(),
                    ranges::back_inserter(to_vector),
                    [](const auto i)
                    {
                       return i % 3;
                    });
// or, alternatively,
//  std::vector<int> to_vector(from_vector.size());
//  std::copy(from_vector, to_vector.begin());
 
    std::cout << "to_vector contains: ";
 
    ranges::copy(to_vector, ranges::ostream_iterator<int>(std::cout, " "));
    std::cout << '\n';
}

Ausgabe

to_vector contains: 1 2 4 5 7 8

[edit] Siehe auch

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