table of contents
std::ranges::subrange::operatorPairLike(3) | C++ Standard Libary | std::ranges::subrange::operatorPairLike(3) |
NAME¶
std::ranges::subrange::operatorPairLike - std::ranges::subrange::operatorPairLike
Synopsis¶
template< /* see below */ PairLike >
requires pair-like-convertible-from<PairLike, (1) (since
C++20)
const I&, const S&>
constexpr operator PairLike() const;
Helper concepts
template< class T >
concept pair-like =
!std::is_reference_v<T> && requires(T t) {
typename std::tuple_size<T>::type; //
ensures std::tuple_size<T>
// is
complete
requires
std::derived_from<std::tuple_size<T>,
(until C++23)
std::integral_constant<std::size_t, 2>>; (2) (exposition
typename std::tuple_element_t<0, only*)
std::remove_const_t<T>>;
typename std::tuple_element_t<1,
std::remove_const_t<T>>;
{ std::get<0>(t) } -> std::convertible_to<
const
std::tuple_element_t<0, T>&>;
{ std::get<1>(t) } -> std::convertible_to<
const
std::tuple_element_t<1, T>&>;
};
template< class T, class U, class V >
concept pair-like-convertible-from =
!ranges::range<T> && pair-like<T> && (until
C++23)
std::constructible_from<T, U, V> && (exposition
convertible-to-non-slicing<U, only*)
std::tuple_element_t<0, T>> &&
std::convertible_to<V, std::tuple_element_t<1,
T>>;
template< class T, class U, class V > (3)
concept pair-like-convertible-from =
!ranges::range<T> && !std::is_reference_v<T>
&& pair-like<T> && (since C++23)
std::constructible_from<T, U, V> && (exposition
convertible-to-non-slicing<U, only*)
std::tuple_element_t<0, T>> &&
std::convertible_to<V, std::tuple_element_t<1,
T>>;
1) Converts subrange to a pair-like type (i.e. a type models
the helper concept pair-like defined below
(until C++23)
pair-like
(since C++23)). Equivalent to return PairLike(i_, s_);, where i_ and s_ are
the
stored iterator and sentinel respectively.
PairLike is constrained that
std::same_as<std::remove_cvref_t<PairLike>, subrange>
is false.
This conversion function has additional constraints imposed by
pair-like-convertible
(see below).
2) The exposition-only concept pair-like specifies a type is pair-like.
Generally,
an expression e of a pair-like type can be used for structured binding (i.e.
auto
const& [x, y] = e; is generally well-formed).
This concept is replaced by the library-wide exposition-only concept
pair-like.
(since C++23)
3) The exposition-only concept pair-like-convertible-from refines pair-like.
It
* rejects
reference types and
(since C++23)range types,
* requires that U and V are convertible to the first and second element type
of T
respectively, and
* requires the conversion from U (which will be replaced by const I&) to
the first
element type to be non-slicing (see convertible-to-non-slicing).
Parameters¶
(none)
Return value¶
A PairLike value direct-initialized with the stored iterator and sentinel.
Notes¶
Following types in the standard library are pair-like:
* std::pair<T, U>
* std::tuple<T, U>
* std::array<T, 2>
* std::ranges::subrange<I, S, K>
* std::complex<T> (since C++26)
A program-defined type derived from one of these types can be a
pair-like type, if
* std::tuple_size and std::tuple_element are correctly specialized (until
C++23)
for it, and
* calls to std::get<0> and std::get<1> for its value are
well-formed.
Since subrange specializations are range types, conversion to them are not
performed
via this conversion function.
std::array specializations cannot be converted from subrange, since they are
range
types.
Example¶
// Run this code
#include <iostream>
#include <ranges>
#include <string>
#include <utility>
using striter = std::string::const_iterator;
using legacy_strview = std::pair<striter, striter>;
void legacy_print(legacy_strview p)
{
for (; p.first != p.second; ++p.first)
std::cout << *p.first << ' ';
std::cout << '\n';
}
int main()
{
std::string dat{"ABCDE"};
for (auto v{std::ranges::subrange{dat}}; v; v = {v.begin(), v.end() - 1})
{
/*...*/
legacy_print(legacy_strview{v});
}
}
Output:¶
A B C D E
A B C D
A B C
A B
A
2024.06.10 | http://cppreference.com |