满足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.

  • [...]

对于您的 AA.begin() 是类型 void,不可能是迭代器。因此,ranges::begin(std::declval<A>())无效。