Difference between revisions of "cpp/ranges/range adaptor closure"
From cppreference.com
D41D8CD98F (Talk | contribs) m |
m (→Example: sliced it a bit.) |
||
(4 intermediate revisions by 2 users not shown) | |||
Line 10: | Line 10: | ||
{{tt|std::ranges::range_adaptor_closure}} is a helper class template for defining a {{named req|RangeAdaptorClosureObject}}. | {{tt|std::ranges::range_adaptor_closure}} is a helper class template for defining a {{named req|RangeAdaptorClosureObject}}. | ||
− | Let {{ | + | Let {{c|t}} be the object of type {{tt|T}}, the implementation ensures that {{c|t}} is a range adaptor closure object if all the requirements are met: |
− | * {{ | + | * {{c|t}} is a unary function object that takes one {{lconcept|range}} argument. |
− | * {{tt|T}} has exactly one public base class {{c|ranges::range_adaptor_closure<T>}}, and {{ | + | * {{tt|T}} has exactly one public base class {{c/core|ranges::range_adaptor_closure<T>}}, and {{tt|T}} has no base classes of type {{c/core|ranges::range_adaptor_closure<U>}} for any other type {{tt|U}}. |
* {{tt|T}} does not satisfy {{lconcept|range}}. | * {{tt|T}} does not satisfy {{lconcept|range}}. | ||
+ | |||
+ | ===Notes=== | ||
+ | {{ftm begin}} | ||
+ | {{ftm|__cpp_lib_ranges|value=202202L|std=C++23|{{tt|std::ranges::range_adaptor_closure}}}} | ||
+ | {{ftm end}} | ||
===Example=== | ===Example=== | ||
{{example | {{example | ||
− | + | |code= | |
− | + | ||
#include <ranges> | #include <ranges> | ||
− | |||
#include <string_view> | #include <string_view> | ||
− | // | + | // Define Slice as a range adaptor closure |
− | struct Slice : std::ranges::range_adaptor_closure<Slice> { | + | struct Slice : std::ranges::range_adaptor_closure<Slice> |
+ | { | ||
std::size_t start = 0; | std::size_t start = 0; | ||
std::size_t end = std::string_view::npos; | std::size_t end = std::string_view::npos; | ||
− | std::string_view operator()(std::string_view sv) const { | + | constexpr std::string_view operator()(std::string_view sv) const |
+ | { | ||
return sv.substr(start, end - start); | return sv.substr(start, end - start); | ||
} | } | ||
}; | }; | ||
− | int main() { | + | int main() |
− | std:: | + | { |
+ | constexpr std::string_view str = "01234567"; | ||
− | Slice slicer{.start = 1, .end = 6}; | + | constexpr Slice slicer{.start = 1, .end = 6}; |
− | auto sv1 = slicer(str); | + | // use slicer as a normal function object |
− | auto sv2 = str {{!}} slicer; | + | constexpr auto sv1 = slicer(str); |
− | + | static_assert(sv1 == "12345"); | |
− | + | ||
+ | // use slicer as a range adaptor closure object | ||
+ | constexpr auto sv2 = str {{!}} slicer; | ||
+ | static_assert(sv2 == "12345"); | ||
// range adaptor closures can be composed | // range adaptor closures can be composed | ||
− | auto slice_and_drop = slicer | + | constexpr auto slice_and_drop = slicer {{!}} std::views::drop(2); |
− | + | static_assert(std::string_view(str {{!}} slice_and_drop) == "345"); | |
− | + | ||
} | } | ||
− | |||
− | |||
− | |||
− | |||
}} | }} | ||
+ | |||
+ | {{langlinks|de|es|ja|ru|zh}} |
Latest revision as of 13:23, 10 September 2024
Defined in header <ranges>
|
||
template< class D > requires std::is_object_v<D> && std::same_as<D, std::remove_cv_t<D>> |
(since C++23) | |
std::ranges::range_adaptor_closure
is a helper class template for defining a RangeAdaptorClosureObject.
Let t be the object of type T
, the implementation ensures that t is a range adaptor closure object if all the requirements are met:
- t is a unary function object that takes one
range
argument. -
T
has exactly one public base class ranges::range_adaptor_closure<T>, andT
has no base classes of type ranges::range_adaptor_closure<U> for any other typeU
. -
T
does not satisfyrange
.
[edit] Notes
Feature-test macro | Value | Std | Feature |
---|---|---|---|
__cpp_lib_ranges |
202202L | (C++23) | std::ranges::range_adaptor_closure
|
[edit] Example
Run this code
#include <ranges> #include <string_view> // Define Slice as a range adaptor closure struct Slice : std::ranges::range_adaptor_closure<Slice> { std::size_t start = 0; std::size_t end = std::string_view::npos; constexpr std::string_view operator()(std::string_view sv) const { return sv.substr(start, end - start); } }; int main() { constexpr std::string_view str = "01234567"; constexpr Slice slicer{.start = 1, .end = 6}; // use slicer as a normal function object constexpr auto sv1 = slicer(str); static_assert(sv1 == "12345"); // use slicer as a range adaptor closure object constexpr auto sv2 = str | slicer; static_assert(sv2 == "12345"); // range adaptor closures can be composed constexpr auto slice_and_drop = slicer | std::views::drop(2); static_assert(std::string_view(str | slice_and_drop) == "345"); }