Namespaces
Variants

std:: set_difference

From cppreference.net
Algorithm library
Constrained algorithms and algorithms on ranges (C++20)
Constrained algorithms, e.g. ranges::copy , ranges::sort , ...
Execution policies (C++17)
Non-modifying sequence operations
Batch operations
(C++17)
Search operations
Modifying sequence operations
Copy operations
(C++11)
(C++11)
Swap operations
Transformation operations
Generation operations
Removing operations
Order-changing operations
(until C++17) (C++11)
(C++20) (C++20)
Sampling operations
(C++17)

Sorting and related operations
Partitioning operations
Sorting operations
Binary search operations
(on partitioned ranges)
Set operations (on sorted ranges)
Merge operations (on sorted ranges)
Heap operations
Minimum/maximum operations
Lexicographical comparison operations
Permutation operations
C library
Numeric operations
Operations on uninitialized memory
Definiert im Header <algorithm>
template < class InputIt1, class InputIt2, class OutputIt >

OutputIt set_difference ( InputIt1 first1, InputIt1 last1,
InputIt2 first2, InputIt2 last2,

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

class ForwardIt1, class ForwardIt2, class ForwardIt3 >
ForwardIt3 set_difference ( ExecutionPolicy && policy,
ForwardIt1 first1, ForwardIt1 last1,
ForwardIt2 first2, ForwardIt2 last2,

ForwardIt3 d_first ) ;
(2) (seit C++17)
template < class InputIt1, class InputIt2,

class OutputIt, class Compare >
OutputIt set_difference ( InputIt1 first1, InputIt1 last1,
InputIt2 first2, InputIt2 last2,

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

class ForwardIt1, class ForwardIt2,
class ForwardIt3, class Compare >
ForwardIt3 set_difference ( ExecutionPolicy && policy,
ForwardIt1 first1, ForwardIt1 last1,
ForwardIt2 first2, ForwardIt2 last2,

ForwardIt3 d_first, Compare comp ) ;
(4) (seit C++17)

Kopiert die Elemente aus dem sortierten Bereich [ first1 , last1 ) , die nicht im sortierten Bereich [ first2 , last2 ) gefunden werden, in den Bereich beginnend bei d_first . Der Ausgabebereich ist ebenfalls sortiert.

Falls [ first1 , last1 ) m äquivalente Elemente enthält und [ first2 , last2 ) n dazu äquivalente Elemente enthält, werden die letzten std:: max ( m - n, 0 ) Elemente aus [ first1 , last1 ) in den Ausgabebereich kopiert, wobei die Reihenfolge erhalten bleibt.

1) Falls [ first1 , last1 ) oder [ first2 , last2 ) nicht sortiert ist bezüglich operator < (bis C++20) std:: less { } (seit C++20) , ist das Verhalten undefiniert.
3) Falls [ first1 , last1 ) oder [ first2 , last2 ) nicht bezüglich comp sortiert ist, ist das Verhalten undefiniert.
2,4) Gleich wie (1,3) , aber ausgeführt gemäß policy .
Diese Überladungen nehmen nur dann an der Überladungsauflösung teil, 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)

Wenn der Ausgabebereich sich mit [ first1 , last1 ) oder [ first2 , last2 ) überschneidet, ist das Verhalten undefiniert.

Inhaltsverzeichnis

Parameter

first1, last1 - das Paar von Iteratoren, das den ersten sortierten Eingabe- Bereich der zu untersuchenden Elemente definiert
first2, last2 - das Paar von Iteratoren, das den zweiten sortierten Eingabe- Bereich der zu durchsuchenden Elemente definiert
d_first - der Anfang des Ausgabebereichs
policy - die zu verwendende Ausführungsrichtlinie
comp - Vergleichsfunktionsobjekt (d.h. ein Objekt, das die Anforderungen von Compare erfüllt), das ​ true zurückgibt, wenn das erste Argument kleiner als (d.h. vor dem zweiten geordnet ist) das zweite.

Die Signatur der Vergleichsfunktion sollte äquivalent zu Folgender sein:

bool cmp ( const Type1 & a, const Type2 & b ) ;

Obwohl die Signatur nicht const & benötigt, darf die Funktion die übergebenen Objekte nicht modifizieren und muss alle Werte der Typen (möglicherweise const) Type1 und Type2 unabhängig von der Wertkategorie akzeptieren können (daher ist Type1& nicht erlaubt , ebenso wenig wie Type1 , es sei denn, für Type1 ist eine Verschiebung äquivalent zu einer Kopie (seit C++11) ).
Die Typen Type1 und Type2 müssen so beschaffen sein, dass Objekte der Typen InputIt1 und InputIt2 dereferenziert und dann implizit sowohl zu Type1 als auch zu Type2 konvertiert werden können. ​

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

Rückgabewert

Iterator hinter das Ende des konstruierten Bereichs.

Komplexität

Gegeben N 1 als std:: distance ( first1, last1 ) und N 2 als std:: distance ( first2, last2 ) :

1,2) Höchstens 2⋅(N 1 +N 2 )-1 Vergleiche unter Verwendung von operator < (bis C++20) std:: less { } (seit C++20) .
3,4) Höchstens 2⋅(N 1 +N 2 )-1 Anwendungen der Vergleichsfunktion comp .

Ausnahmen

Die Überladungen mit einem Template-Parameter namens ExecutionPolicy melden Fehler wie folgt:

  • Wenn die Ausführung einer als Teil des Algorithmus aufgerufenen Funktion eine Exception wirft und ExecutionPolicy einer der Standard-Policies ist, wird std::terminate aufgerufen. Für jede andere ExecutionPolicy ist das Verhalten implementierungsdefiniert.
  • Wenn der Algorithmus keinen Speicher allozieren kann, wird std::bad_alloc geworfen.

Mögliche Implementierung

set_difference (1)
template<class InputIt1, class InputIt2, class OutputIt>
OutputIt set_difference(InputIt1 first1, InputIt1 last1,
                        InputIt2 first2, InputIt2 last2, OutputIt d_first)
{
    while (first1 != last1)
    {
        if (first2 == last2)
            return std::copy(first1, last1, d_first);
        if (*first1 < *first2)
            *d_first++ = *first1++;
        else
        {
            if (! (*first2 < *first1))
                ++first1;
            ++first2;
        }
    }
    return d_first;
}
set_difference (3)
template<class InputIt1, class InputIt2, class OutputIt, class Compare>
OutputIt set_difference(InputIt1 first1, InputIt1 last1,
                        InputIt2 first2, InputIt2 last2, OutputIt d_first, Compare comp)
{
    while (first1 != last1)
    {
        if (first2 == last2)
            return std::copy(first1, last1, d_first);
        if (comp(*first1, *first2))
            *d_first++ = *first1++;
        else
        {
            if (!comp(*first2, *first1))
                ++first1;
            ++first2;
        }
    }
    return d_first;
}

Beispiel

#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>
template<typename T>
std::ostream& operator<<(std::ostream& os, const std::vector<T>& v)
{
    os << '{';
    for (auto n{v.size()}; const auto& e : v)
        os << e << (--n ? ", " : "");
    return os << '}';
}
struct Order // eine Struktur mit sehr interessanten Daten
{
    int order_id{};
    friend std::ostream& operator<<(std::ostream& os, const Order& ord)
    {
        return os << ord.order_id;
    }
};
int main()
{
    const std::vector<int> v1{1, 2, 5, 5, 5, 9};
    const std::vector<int> v2{2, 5, 7};
    std::vector<int> diff;
    std::set_difference(v1.begin(), v1.end(), v2.begin(), v2.end(),
                        std::inserter(diff, diff.begin()));
    std::cout << v1 << " ∖ " << v2 << " == " << diff << "\n\n";
    // wir möchten wissen, welche Bestellungen zwischen altem und neuem Zustand "ausgeschnitten" werden:
    std::vector<Order> old_orders{{1}, {2}, {5}, {9}};
    std::vector<Order> new_orders{{2}, {5}, {7}};
    std::vector<Order> cut_orders;
    std::set_difference(old_orders.begin(), old_orders.end(),
                        new_orders.begin(), new_orders.end(),
                        std::back_inserter(cut_orders),
                        [](auto& a, auto& b) { return a.order_id < b.order_id; });
    std::cout << "alte Bestellungen: " << old_orders << '\n'
              << "neue Bestellungen: " << new_orders << '\n'
              << "ausgeschnittene Bestellungen: " << cut_orders << '\n';
}

Ausgabe:

{1, 2, 5, 5, 5, 9} ∖ {2, 5, 7} == {1, 5, 5, 9}
alte Bestellungen: {1, 2, 5, 9}
neue Bestellungen: {2, 5, 7}
ausgeschnittene Bestellungen: {1, 9}

Fehlerberichte

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

DR Angewendet auf Verhalten wie veröffentlicht Korrektes Verhalten
LWG 291 C++98 es war nicht spezifiziert, wie äquivalente Elemente in den Eingabebereichen zu behandeln sind spezifiziert

Siehe auch

gibt true zurück, falls eine Sequenz eine Teilsequenz einer anderen ist
(Funktionsschablone)
berechnet die symmetrische Differenz zwischen zwei Mengen
(Funktionsschablone)
berechnet die Differenz zwischen zwei Mengen
(Algorithmus-Funktionsobjekt)