Namespaces
Variants
Views
Actions

Difference between revisions of "cpp/ranges/dangling"

From cppreference.com
< cpp‎ | ranges
(P1252R2 dangling)
 
(models->model)
 
(9 intermediate revisions by 4 users not shown)
Line 9: Line 9:
 
{{dcl end}}
 
{{dcl end}}
  
{{tt|dangling}} is a placeholder type and an empty class type, used together with the template aliases {{ltt|cpp/ranges/safe_iterator_t|ranges::safe_iterator_t}} and {{ltt|cpp/ranges/safe_iterator_t|ranges::safe_subrange_t}}.
+
{{tt|dangling}} is a placeholder type and an empty class type, used together with the template aliases {{ltt|cpp/ranges/borrowed_iterator_t|ranges::borrowed_iterator_t}} and {{ltt|cpp/ranges/borrowed_iterator_t|ranges::borrowed_subrange_t}}.
  
When some [[cpp/algorithm/ranges|constrain algorithms]] that usually return an iterator or a subrange of a {{lconcept|Range}} take a particular rvalue {{tt|Range}} argument that does not models exposition-only concept {{ltt|cpp/ranges/Range|__ForwardingRange}}, {{tt|dangling}} will be returned instead to avoid returning potentially dangling results.
+
When some [[cpp/algorithm/ranges|constrained algorithms]] that usually return an iterator or a subrange of a {{lconcept|range}} take a particular rvalue {{tt|range}} argument that does not model {{lconcept|borrowed_range}}, {{tt|dangling}} will be returned instead to avoid returning potentially dangling results.
  
 
===Member functions===
 
===Member functions===
Line 27: Line 27:
 
@1@ {{tt|dangling}} is trivially default constructible.
 
@1@ {{tt|dangling}} is trivially default constructible.
 
@2@ {{tt|dangling}} can be constructed from arguments of arbitrary number and arbitrary non-void type. The construction does not have any side-effect itself.
 
@2@ {{tt|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 the well-formed non-aggregate initialization with {{tt|dangling}}, the resulting initialization is also well-formed.
+
In other words, after replacing the type (e.g. an iterator type) in a well-formed non-aggregate initialization with {{tt|dangling}}, the resulting initialization is also well-formed.
 
}}
 
}}
  
 
===Example===
 
===Example===
{{example}}
+
{{example|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'
 +
}}
  
 
===See also===
 
===See also===
 
{{dsc begin}}
 
{{dsc begin}}
{{dsc inc | cpp/ranges/dsc safe_iterator_t}}
+
{{dsc inc | cpp/ranges/dsc borrowed_iterator_t}}
 +
{{dsc inc | cpp/ranges/dsc borrowed_range}}
 
{{dsc end}}
 
{{dsc end}}
  
{{langlinks|ja|zh}}
+
{{langlinks|es|ja|ru|zh}}

Latest revision as of 17:20, 18 September 2021

 
 
Ranges library
Range adaptors
 
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.

Contents

[edit] Member functions

std::ranges::dangling::dangling

constexpr dangling() noexcept = default;
(1)
template<class... Args>
constexpr dangling(Args&&...) noexcept { }
(2)
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

#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'

[edit] See also

obtains iterator type or subrange type of a borrowed_range
(alias template)[edit]
specifies that a type is a range and iterators obtained from an expression of it can be safely returned without danger of dangling
(concept) [edit]