Namespaces
Variants

std::ranges::ends_with

Von de.cppreference.net
 
 
Algorithmenbibliothek
Eingeschränkte Algorithmen und Algorithmen auf Bereichen (C++20)
Eingeschränkte Algorithmen, z.B. ranges::copy, ranges::sort, ...
Nicht modifizierende Sequenzoperationen    
Stapeloperationen
(C++17)
Suchoperationen
Modifizierende Sequenzoperationen
Kopieroperationen
(C++11)
(C++11)
Tauschoperationen
Transformationsoperationen
Generierungsoperationen
Entfernungsoperationen
Reihenfolgeändernde Operationen
(bis C++17)(C++11)
(C++20)(C++20)
Stichprobenoperationen
(C++17)

Sortier- und verwandte Operationen
Partitionierungsoperationen
(C++11)    

Sortieroperationen
Binäre Suchoperationen
(auf partitionierten Bereichen)
Mengenoperationen (auf sortierten Bereichen)
Mischoperationen (auf sortierten Bereichen)
Heap-Operationen
Minimum/Maximum-Operationen
(C++11)
(C++17)
Lexikografische Vergleichsoperationen
Permutationsoperationen


 
Eingeschränkte Algorithmen
Alle Namen in diesem Menü gehören zum Namensraum std::ranges
Nicht modifizierende Sequenzoperationen
Modifizierende Sequenzoperationen
Partitionierungsoperationen
Sortieroperationen
Binäre Suchoperationen (auf sortierten Bereichen)
       
       
Mengenoperationen (auf sortierten Bereichen)
Heap-Operationen
Minimum/Maximum-Operationen
       
       
Permutationsoperationen
Faltungsoperationen
Operationen auf nicht initialisiertem Speicher
Rückgabetypen
 
Definiert in Header <algorithm>
Aufrufsignatur
template< std::input_iterator I1, std::sentinel_for<I1> S1,
          std::input_iterator I2, std::sentinel_for<I2> S2,
          class Pred = ranges::equal_to,
          class Proj1 = std::identity, class Proj2 = std::identity >
requires (std::forward_iterator<I1> || std::sized_sentinel_for<S1, I1>) &&
         (std::forward_iterator<I2> || std::sized_sentinel_for<S2, I2>) &&
         std::indirectly_comparable<I1, I2, Pred, Proj1, Proj2>
constexpr bool ends_with( I1 first1, S1 last1,
                          I2 first2, S2 last2, Pred pred = {},
                          Proj1 proj1 = {}, Proj2 proj2 = {} );
(1) (seit C++23)
template< ranges::input_range R1, ranges::input_range R2,
          class Pred = ranges::equal_to,
          class Proj1 = std::identity, class Proj2 = std::identity >
requires (ranges::forward_range<R1> || ranges::sized_range<R1>) &&
         (ranges::forward_range<R2> || ranges::sized_range<R2>) &&
         std::indirectly_comparable<ranges::iterator_t<R1>,
                                    ranges::iterator_t<R2>,
                                    Pred, Proj1, Proj2>
constexpr bool ends_with( R1&& r1, R2&& r2, Pred pred = {},
                          Proj1 proj1 = {}, Proj2 proj2 = {} );
(2) (seit C++23)

Prüft, ob der zweite Bereich das Suffix des ersten Bereichs ist.

1) Sei N1 sei ranges::distance(first1, last1) und N2 sei ranges::distance(first2, last2):
  • Falls N1 < N2 ist true, gibt false zurück.
  • Andernfalls gibt ranges::equal(std::move(first1) + (N1 - N2), last1,
    std::move(first2), last2, pred, proj1, proj2)
    zurück.
2) Sei N1 sei ranges::distance(r1) und N2 sei ranges::distance(r2).
  • Falls N1 < N2 ist true, gibt false zurück.
  • Andernfalls gibt ranges::equal(views::drop(ranges::ref_view(r1),
    N1 - static_cast<decltype(N1)>(N2)),
    r2, pred, proj1, proj2)
    zurück.

Die auf dieser Seite beschriebenen funktionsähnlichen Entitäten sind Algorithmus-Funktionsobjekte (informell bekannt als niebloids), das heißt:

Parameter

first1, last1 - das Iterator-Sentinel-Paar, das den Bereich der zu untersuchenden Elemente definiert
r1 - der Bereich der zu untersuchenden Elemente
first2, last2 - das Iterator-Sentinel-Paar, das den Bereich der als Suffix zu verwendenden Elemente definiert
r2 - der Bereich der als Suffix zu verwendenden Elemente
pred - das binäre Prädikat, das die projizierten Elemente vergleicht
proj1 - die Projektion, die auf die Elemente des zu untersuchenden Bereichs angewendet wird
proj2 - die Projektion, die auf die Elemente des als Suffix zu verwendenden Bereichs angewendet wird

Rückgabewert

true wahr, wenn der zweite Bereich das Suffix des ersten Bereichs ist, false sonst.

Komplexität

Im Allgemeinen linear: höchstens min(N1,N2) Anwendungen des Prädikats und beider Projektionen. Das Prädikat und beide Projektionen werden nicht angewendet, wenn N1 < N2 ist true.

Wenn sowohl N1 als auch N2 in konstanter Zeit berechnet werden können (d.h. beide Iterator-Sentinel-Typ-Paare modellieren sized_sentinel_for, oder beide Bereichstypen modellieren sized_range) und N1 < N2 ist true, ist die Zeitkomplexität konstant.

Mögliche Implementierung

struct ends_with_fn
{
    template<std::input_iterator I1, std::sentinel_for<I1> S1,
             std::input_iterator I2, std::sentinel_for<I2> S2,
             class Pred = ranges::equal_to,
             class Proj1 = std::identity, class Proj2 = std::identity>
    requires (std::forward_iterator<I1> || std::sized_sentinel_for<S1, I1>) &&
             (std::forward_iterator<I2> || std::sized_sentinel_for<S2, I2>) &&
             std::indirectly_comparable<I1, I2, Pred, Proj1, Proj2>
    constexpr bool operator()(I1 first1, S1 last1, I2 first2, S2 last2,
                              Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}) const
    {
        const auto n1 = ranges::distance(first1, last1);
        const auto n2 = ranges::distance(first2, last2);
        if (n1 < n2)
            return false;
        ranges::advance(first1, n1 - n2);
        return ranges::equal(std::move(first1), last1,
                             std::move(first2), last2,
                             pred, proj1, proj2);
    }
    
    template<ranges::input_range R1, ranges::input_range R2,
             class Pred = ranges::equal_to,
             class Proj1 = std::identity, class Proj2 = std::identity>
    requires (ranges::forward_range<R1> || ranges::sized_range<R1>) &&
             (ranges::forward_range<R2> || ranges::sized_range<R2>) &&
             std::indirectly_comparable<ranges::iterator_t<R1>,
                                        ranges::iterator_t<R2>,
                                        Pred, Proj1, Proj2>
    constexpr bool operator()(R1&& r1, R2&& r2,
                              Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}) const
    {
        const auto n1 = ranges::distance(r1);
        const auto n2 = ranges::distance(r2);
        if (n1 < n2)
            return false;
        return ranges::equal(views::drop(ranges::ref_view(r1),
                                         n1 - static_cast<decltype(n1)>(n2)),
                             r2, pred, proj1, proj2);
    }
};

inline constexpr ends_with_fn ends_with{};

Hinweise

Feature-Test-Makro Wert Std Feature
__cpp_lib_ranges_starts_ends_with 202106L (C++23) std::ranges::starts_with, std::ranges::ends_with

Beispiel

#include <algorithm>
#include <array>

static_assert
(
    ! std::ranges::ends_with("for", "cast") &&
    std::ranges::ends_with("dynamic_cast", "cast") &&
    ! std::ranges::ends_with("as_const", "cast") &&
    std::ranges::ends_with("bit_cast", "cast") &&
    ! std::ranges::ends_with("to_underlying", "cast") &&
    std::ranges::ends_with(std::array{1, 2, 3, 4}, std::array{3, 4}) &&
    ! std::ranges::ends_with(std::array{1, 2, 3, 4}, std::array{4, 5})
);

int main() {}

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 4105 C++23 Überladung (2) berechnete die Größen
differenz um N1 - N2[1]
geändert zu
N1 - static_cast<decltype(N1)>(N2)
  1. ↑ Sein Ergebnis könnte von einem Integer-Klassentyp sein, in diesem Fall kann ranges::drop_view nicht konstruiert werden.

Siehe auch

prüft, ob ein Bereich mit einem anderen Bereich beginnt
(Algorithmus-Funktionsobjekt)
(C++20)
prüft, ob der String mit dem angegebenen Suffix endet
(öffentliche Mitgliedsfunktion von std::basic_string<CharT,Traits,Allocator>)
(C++20)
prüft, ob der String-View mit dem angegebenen Suffix endet
(öffentliche Mitgliedsfunktion von std::basic_string_view<CharT,Traits>)