std::ranges::leer
| 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 */ |
(seit C++20) | |
Bestimmt, ob t Elemente enthält.
Ein Aufruf von ranges::empty ist ausdrucksäquivalent zu
- bool(t.empty()), falls dieser Ausdruck gültig ist.
- Andernfalls (ranges::size(t) == 0), falls dieser Ausdruck gültig ist.
- 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
- std::invocable<__empty_fn, Args...>,
- std::invocable<const __empty_fn, Args...>,
- std::invocable<__empty_fn&, Args...>, und
- std::invocable<const __empty_fn&, Args...>.
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) |