std::ranges::dangling
From cppreference.com
C++
Feature test macros (C++20)
Concepts library (C++20)
Metaprogramming library (C++11)
Ranges library (C++20)
Filesystem library (C++17)
Concurrency support library (C++11)
Execution control library (C++26)
Ranges library
(C++23)(C++23)
(C++26)(C++26)
(C++23)(C++23)
(C++26)(C++26)
(C++26)(C++26)
(C++23)(C++23)
(C++23)(C++23)
(C++23)(C++23)
(C++23)(C++23)
(C++23)(C++23)
(C++23)
(C++23)(C++23)
(C++23)
(C++23)(C++23)
(C++23)(C++23)
(C++23)(C++23)
(C++23)(C++23)
(C++23)(C++23)
Defined in header
<ranges>
struct dangling;
(since C++20)
dangling
is a placeholder type and an empty class type, used together with the template aliases ranges::borrowed_iterator_t and ranges::borrowed_subrange_t.
When some constrained algorithms that usually return an iterator or a subrange of a range
take a particular rvalue range
argument that does not model borrowed_range
, dangling
will be returned instead to avoid returning potentially dangling results.
[edit] Member functions
std::ranges::dangling::dangling
constexpr dangling() noexcept = default;
(1)
template<class... Args>
constexpr dangling(Args&&...) noexcept { }
(2)
constexpr dangling(Args&&...) noexcept { }
1)
dangling
is trivially default constructible.2)
dangling
can be constructed from arguments of arbitrary number and arbitrary non-void type. The construction does not have any side-effect itself.
In other words, after replacing the type (e.g. an iterator type) in a well-formed non-aggregate initialization with dangling
, the resulting initialization is also well-formed.
[edit] Example
Run this code
#include <algorithm> #include <array> #include <iostream> #include <ranges> #include <type_traits> #include <string_view> int main() { auto get_array_by_value = [] { return std::array {0, 1, 0, 1}; }; auto dangling_iter = std::ranges::max_element (get_array_by_value()); static_assert(std::is_same_v <std::ranges::dangling, decltype(dangling_iter)>); // std::cout << *dangling_iter << '\n'; // compilation error: no match for 'operator*' // (operand type is 'std::ranges::dangling') auto get_persistent_array = []() -> const std::array <int, 4>& { static constexpr std::array a{0, 1, 0, 1}; return a; }; auto valid_iter = std::ranges::max_element (get_persistent_array()); static_assert(!std::is_same_v <std::ranges::dangling, decltype(valid_iter)>); std::cout << *valid_iter << ' '; // 1 auto get_string_view = [] { return std::string_view {"alpha"}; }; auto valid_iter2 = std::ranges::min_element (get_string_view()); // OK: std::basic_string_view models borrowed_range static_assert(!std::is_same_v <std::ranges::dangling, decltype(valid_iter2)>); std::cout << '\'' << *valid_iter2 << '\'' << '\n'; // 'a' }
Output:
1 'a'