Namensräume
Varianten
Aktionen

std::ranges::leer

Von cppreference.com
< cpp‎ | ranges
 
 
Bereichsbibliothek
Range-Adaptoren
 
Definiert in der Header-Datei <ranges>
Definiert in Header <iterator>
inline namespace /*nicht spezifiziert*/ {

    inline constexpr auto leer = /*nicht spezifiziert*/;

}
(seit C++20)
(Customization-Point-Objekt)
Aufruf-Signatur
template< class T >

    requires /* siehe unten */

constexpr bool leer( T&& t );
(seit C++20)

Bestimmt, ob t Elemente enthält.

Ein Aufruf von ranges::empty ist ausdrucksäquivalent zu

  1. bool(t.empty()), falls dieser Ausdruck gültig ist.
  2. Andernfalls (ranges::size(t) == 0), falls dieser Ausdruck gültig ist.
  3. Andernfalls bool(ranges::begin(t) == ranges::end(t)), falls dieser Ausdruck gültig ist und decltype(ranges::begin(t)) std::forward_iterator modelliert.

In allen anderen Fällen ist ein Aufruf von ranges::empty ill-formed, was zu einem Substitutionsfehler führen kann, wenn ranges::empty(t) im direkten Kontext einer Vorlageninstanziierung erscheint.

Customization Point Objects

Der Name ranges::empty bezeichnet ein Customization Point Object, welches ein const Function Object eines literalen semiregular-Klassentyps ist. Zu Auslegungszwecken wird die cv-unqualifizierte Version seines Typs als __empty_fn bezeichnet.

Alle Instanzen von __empty_fn sind gleich. Die Auswirkungen des Aufrufs verschiedener Instanzen des Typs __empty_fn auf dieselben Argumente sind äquivalent, unabhängig davon, ob der Ausdruck, der die Instanz bezeichnet, ein lvalue oder rvalue ist und ob er const-qualifiziert ist oder nicht (jedoch ist eine volatile-qualifizierte Instanz nicht notwendigerweise aufrufbar). Daher kann ranges::empty frei kopiert werden und seine Kopien können austauschbar verwendet werden.

Gegeben eine Menge von Typen Args..., wenn std::declval<Args>()... die obigen Anforderungen für Argumente an ranges::empty erfüllen, modelliert __empty_fn

Andernfalls nimmt kein Funktionsaufrufoperator von __empty_fn an der Überladungsauflösung teil.

[bearbeiten] Beispiel

#include <iostream>
#include <ranges>
#include <vector>
 
template<std::ranges::input_range R>
void print(char id, R&& r)
{
    if (std::ranges::empty(r))
    {
        std::cout << '\t' << id << ") Empty\n";
        return;
    }
 
    std::cout << '\t' << id << ") Elements:";
    for (const auto& element : r)
        std::cout << ' ' << element;
    std::cout << '\n';
}
 
int main()
{
    {
        auto v = std::vector<int>{1, 2, 3};
        std::cout << "(1) ranges::empty uses std::vector::empty:\n";
        print('a', v);
 
        v.clear();
        print('b', v);
    }
    {
        std::cout << "(2) ranges::empty uses ranges::size(initializer_list):\n";
        auto il = {7, 8, 9};
        print('a', il);
 
        print('b', std::initializer_list<int>{});
    }
    {
        std::cout << "(2) ranges::empty on a raw array uses ranges::size:\n";
        int array[] = {4, 5, 6}; // array has a known bound
        print('a', array);
    }
    {
        struct Scanty : private std::vector<int>
        {
            using std::vector<int>::begin;
            using std::vector<int>::end;
            using std::vector<int>::push_back;
            // Note: both empty() and size() are hidden
        };
 
        std::cout << "(3) calling ranges::empty on an object w/o empty() or size():\n";
        Scanty y;
        print('a', y);
        y.push_back(42);
        print('b', y);
    }
}

Ausgabe

(1) ranges::empty uses std::vector::empty:
        a) Elements: 1 2 3
        b) Empty
(2) ranges::empty uses ranges::size(initializer_list):
        a) Elements: 7 8 9
        b) Empty
(2) ranges::empty on a raw array uses ranges::size:
        a) Elements: 4 5 6
(3) calling ranges::empty on an object w/o empty() or size():
        a) Empty
        b) Elements: 42

[bearbeiten] Siehe auch

(C++17)
prüft, ob der Container leer ist
(function template) [bearbeiten]