满足std::ranges::range个概念
Satisfy std::ranges::range concept
在即将发布的 C++20 范围中,将有具有以下定义的 range concept:
template< class T >
concept range = __RangeImpl<T&>; // exposition-only definition
template< class T >
concept __RangeImpl = requires(T&& t) {
ranges::begin(std::forward<T>(t)); // equality-preserving for forward iterators
ranges::end (std::forward<T>(t));
};
template< class T >
concept __ForwardingRange = ranges::range<T> && __RangeImpl<T>;
将其翻译成简单的英语我会说类型满足范围概念的唯一要求是可以使用 ranges::begin 和 ranges::end 调用。
但是,如果我创建一个只有开始和结束的空类型,那么对范围概念的静态断言会失败吗?
namespace ranges = std::experimental::ranges;
struct A {
void begin() {}
void end() {}
};
static_assert(ranges::range<A>);
我错过了什么?
根据 [range.access.begin]:(强调我的)
The name ranges::begin
denotes a customization point
object. The
expression ranges::begin(E)
for some subexpression E
is
expression-equivalent to:
[...]
Otherwise, if E
is an lvalue, decay-copy(E.begin())
if it is a valid expression and its type I
models
input_or_output_iterator
.
[...]
对于您的 A
,A.begin()
是类型 void
,不可能是迭代器。因此,ranges::begin(std::declval<A>())
无效。
在即将发布的 C++20 范围中,将有具有以下定义的 range concept:
template< class T >
concept range = __RangeImpl<T&>; // exposition-only definition
template< class T >
concept __RangeImpl = requires(T&& t) {
ranges::begin(std::forward<T>(t)); // equality-preserving for forward iterators
ranges::end (std::forward<T>(t));
};
template< class T >
concept __ForwardingRange = ranges::range<T> && __RangeImpl<T>;
将其翻译成简单的英语我会说类型满足范围概念的唯一要求是可以使用 ranges::begin 和 ranges::end 调用。
但是,如果我创建一个只有开始和结束的空类型,那么对范围概念的静态断言会失败吗?
namespace ranges = std::experimental::ranges;
struct A {
void begin() {}
void end() {}
};
static_assert(ranges::range<A>);
我错过了什么?
根据 [range.access.begin]:(强调我的)
The name
ranges::begin
denotes a customization point object. The expressionranges::begin(E)
for some subexpressionE
is expression-equivalent to:
[...]
Otherwise, if
E
is an lvalue,decay-copy(E.begin())
if it is a valid expression and its typeI
modelsinput_or_output_iterator
.[...]
对于您的 A
,A.begin()
是类型 void
,不可能是迭代器。因此,ranges::begin(std::declval<A>())
无效。